From f7382dea1c622148fbc1e3ef1adbe13bd70eb75d Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Sat, 7 Nov 2015 12:22:39 +0100 Subject: [PATCH 001/626] Added class ExportProviderBase --- .../DataExchange/ExportProviderBase.cs | 47 +++++++++++++++++++ .../DataExchange/IExportProvider.cs | 2 +- .../Providers/CategoryXmlExportProvider.cs | 18 ++----- .../Providers/CustomerXlsxExportProvider.cs | 18 ++----- .../Providers/CustomerXmlExportProvider.cs | 18 ++----- .../ManufacturerXmlExportProvider.cs | 18 ++----- .../Providers/OrderXlsxExportProvider.cs | 18 ++----- .../Providers/OrderXmlExportProvider.cs | 18 ++----- .../Providers/ProductXlsxExportProvider.cs | 18 ++----- .../Providers/ProductXmlExportProvider.cs | 18 ++----- .../Providers/SubscriberCsvExportProvider.cs | 18 ++----- .../SmartStore.Services.csproj | 1 + .../Providers/GmcXmlExportProvider.cs | 18 ++----- 13 files changed, 89 insertions(+), 141 deletions(-) create mode 100644 src/Libraries/SmartStore.Services/DataExchange/ExportProviderBase.cs diff --git a/src/Libraries/SmartStore.Services/DataExchange/ExportProviderBase.cs b/src/Libraries/SmartStore.Services/DataExchange/ExportProviderBase.cs new file mode 100644 index 0000000000..f0dd39a95e --- /dev/null +++ b/src/Libraries/SmartStore.Services/DataExchange/ExportProviderBase.cs @@ -0,0 +1,47 @@ +using SmartStore.Core.Domain.DataExchange; + +namespace SmartStore.Services.DataExchange +{ + public abstract class ExportProviderBase : IExportProvider + { + /// + /// The exported entity type + /// + public virtual ExportEntityType EntityType + { + get { return ExportEntityType.Product; } + } + + /// + /// File extension of the export files (without dot). Return null for a non file based, on-the-fly export. + /// + public virtual string FileExtension + { + get { return null; } + } + + /// + /// Get provider specific configuration information. Return null when no provider specific configuration is required. + /// + public virtual ExportConfigurationInfo ConfigurationInfo + { + get { return null; } + } + + /// + /// Export data to a file + /// + /// Export execution context + public virtual void Execute(IExportExecuteContext context) + { + } + + /// + /// Called once per store when export execution ended + /// + /// Export execution context + public virtual void OnExecuted(IExportExecuteContext context) + { + } + } +} diff --git a/src/Libraries/SmartStore.Services/DataExchange/IExportProvider.cs b/src/Libraries/SmartStore.Services/DataExchange/IExportProvider.cs index b0872ef1eb..450c30ed77 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/IExportProvider.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/IExportProvider.cs @@ -6,7 +6,7 @@ namespace SmartStore.Services.DataExchange public partial interface IExportProvider : IProvider, IUserEditable { /// - /// Th exported entity type + /// The exported entity type /// ExportEntityType EntityType { get; } diff --git a/src/Libraries/SmartStore.Services/DataExchange/Providers/CategoryXmlExportProvider.cs b/src/Libraries/SmartStore.Services/DataExchange/Providers/CategoryXmlExportProvider.cs index 5b72bc9d64..e473a28ad2 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Providers/CategoryXmlExportProvider.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Providers/CategoryXmlExportProvider.cs @@ -16,29 +16,24 @@ namespace SmartStore.Services.DataExchange.Providers [SystemName("Exports.SmartStoreCategoryXml")] [FriendlyName("SmartStore XML category export")] [IsHidden(true)] - public class CategoryXmlExportProvider : IExportProvider + public class CategoryXmlExportProvider : ExportProviderBase { public static string SystemName { get { return "Exports.SmartStoreCategoryXml"; } } - public ExportConfigurationInfo ConfigurationInfo - { - get { return null; } - } - - public ExportEntityType EntityType + public override ExportEntityType EntityType { get { return ExportEntityType.Category; } } - public string FileExtension + public override string FileExtension { get { return "XML"; } } - public void Execute(IExportExecuteContext context) + public override void Execute(IExportExecuteContext context) { var settings = new XmlWriterSettings { @@ -104,10 +99,5 @@ public void Execute(IExportExecuteContext context) writer.WriteEndDocument(); } } - - public void OnExecuted(IExportExecuteContext context) - { - // nothing to do - } } } diff --git a/src/Libraries/SmartStore.Services/DataExchange/Providers/CustomerXlsxExportProvider.cs b/src/Libraries/SmartStore.Services/DataExchange/Providers/CustomerXlsxExportProvider.cs index 22a9d229ec..4ab09bd5c5 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Providers/CustomerXlsxExportProvider.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Providers/CustomerXlsxExportProvider.cs @@ -18,7 +18,7 @@ namespace SmartStore.Services.DataExchange.Providers [SystemName("Exports.SmartStoreCustomerXlsx")] [FriendlyName("SmartStore Excel customer export")] [IsHidden(true)] - public class CustomerXlsxExportProvider : IExportProvider + public class CustomerXlsxExportProvider : ExportProviderBase { private string[] Properties { @@ -97,22 +97,17 @@ public static string SystemName get { return "Exports.SmartStoreCustomerXlsx"; } } - public ExportConfigurationInfo ConfigurationInfo - { - get { return null; } - } - - public ExportEntityType EntityType + public override ExportEntityType EntityType { get { return ExportEntityType.Customer; } } - public string FileExtension + public override string FileExtension { get { return "XLSX"; } } - public void Execute(IExportExecuteContext context) + public override void Execute(IExportExecuteContext context) { var invariantCulture = CultureInfo.InvariantCulture; var path = context.FilePath; @@ -214,10 +209,5 @@ public void Execute(IExportExecuteContext context) xlPackage.Save(); } } - - public void OnExecuted(IExportExecuteContext context) - { - // nothing to do - } } } diff --git a/src/Libraries/SmartStore.Services/DataExchange/Providers/CustomerXmlExportProvider.cs b/src/Libraries/SmartStore.Services/DataExchange/Providers/CustomerXmlExportProvider.cs index b88d3d8cd3..93d9c4462b 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Providers/CustomerXmlExportProvider.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Providers/CustomerXmlExportProvider.cs @@ -16,29 +16,24 @@ namespace SmartStore.Services.DataExchange.Providers [SystemName("Exports.SmartStoreCustomerXml")] [FriendlyName("SmartStore XML customer export")] [IsHidden(true)] - public class CustomerXmlExportProvider : IExportProvider + public class CustomerXmlExportProvider : ExportProviderBase { public static string SystemName { get { return "Exports.SmartStoreCustomerXml"; } } - public ExportConfigurationInfo ConfigurationInfo - { - get { return null; } - } - - public ExportEntityType EntityType + public override ExportEntityType EntityType { get { return ExportEntityType.Customer; } } - public string FileExtension + public override string FileExtension { get { return "XML"; } } - public void Execute(IExportExecuteContext context) + public override void Execute(IExportExecuteContext context) { var settings = new XmlWriterSettings { @@ -87,10 +82,5 @@ public void Execute(IExportExecuteContext context) writer.WriteEndDocument(); } } - - public void OnExecuted(IExportExecuteContext context) - { - // nothing to do - } } } diff --git a/src/Libraries/SmartStore.Services/DataExchange/Providers/ManufacturerXmlExportProvider.cs b/src/Libraries/SmartStore.Services/DataExchange/Providers/ManufacturerXmlExportProvider.cs index edc60a007d..8d26a9ab4e 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Providers/ManufacturerXmlExportProvider.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Providers/ManufacturerXmlExportProvider.cs @@ -16,29 +16,24 @@ namespace SmartStore.Services.DataExchange.Providers [SystemName("Exports.SmartStoreManufacturerXml")] [FriendlyName("SmartStore XML manufacturer export")] [IsHidden(true)] - public class ManufacturerXmlExportProvider : IExportProvider + public class ManufacturerXmlExportProvider : ExportProviderBase { public static string SystemName { get { return "Exports.SmartStoreManufacturerXml"; } } - public ExportConfigurationInfo ConfigurationInfo - { - get { return null; } - } - - public ExportEntityType EntityType + public override ExportEntityType EntityType { get { return ExportEntityType.Manufacturer; } } - public string FileExtension + public override string FileExtension { get { return "XML"; } } - public void Execute(IExportExecuteContext context) + public override void Execute(IExportExecuteContext context) { var settings = new XmlWriterSettings { @@ -104,10 +99,5 @@ public void Execute(IExportExecuteContext context) writer.WriteEndDocument(); } } - - public void OnExecuted(IExportExecuteContext context) - { - // nothing to do - } } } diff --git a/src/Libraries/SmartStore.Services/DataExchange/Providers/OrderXlsxExportProvider.cs b/src/Libraries/SmartStore.Services/DataExchange/Providers/OrderXlsxExportProvider.cs index 9f468e071f..ae6ce4271d 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Providers/OrderXlsxExportProvider.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Providers/OrderXlsxExportProvider.cs @@ -15,7 +15,7 @@ namespace SmartStore.Services.DataExchange.Providers [SystemName("Exports.SmartStoreOrderXlsx")] [FriendlyName("SmartStore Excel order export")] [IsHidden(true)] - public class OrderXlsxExportProvider : IExportProvider + public class OrderXlsxExportProvider : ExportProviderBase { private string[] Properties { @@ -96,22 +96,17 @@ public static string SystemName get { return "Exports.SmartStoreOrderXlsx"; } } - public ExportConfigurationInfo ConfigurationInfo - { - get { return null; } - } - - public ExportEntityType EntityType + public override ExportEntityType EntityType { get { return ExportEntityType.Order; } } - public string FileExtension + public override string FileExtension { get { return "XLSX"; } } - public void Execute(IExportExecuteContext context) + public override void Execute(IExportExecuteContext context) { var path = context.FilePath; @@ -250,10 +245,5 @@ public void Execute(IExportExecuteContext context) xlPackage.Save(); } } - - public void OnExecuted(IExportExecuteContext context) - { - // nothing to do - } } } diff --git a/src/Libraries/SmartStore.Services/DataExchange/Providers/OrderXmlExportProvider.cs b/src/Libraries/SmartStore.Services/DataExchange/Providers/OrderXmlExportProvider.cs index a21a94d2f9..15d347847f 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Providers/OrderXmlExportProvider.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Providers/OrderXmlExportProvider.cs @@ -16,29 +16,24 @@ namespace SmartStore.Services.DataExchange.Providers [SystemName("Exports.SmartStoreOrderXml")] [FriendlyName("SmartStore XML order export")] [IsHidden(true)] - public class OrderXmlExportProvider : IExportProvider + public class OrderXmlExportProvider : ExportProviderBase { public static string SystemName { get { return "Exports.SmartStoreOrderXml"; } } - public ExportConfigurationInfo ConfigurationInfo - { - get { return null; } - } - - public ExportEntityType EntityType + public override ExportEntityType EntityType { get { return ExportEntityType.Order; } } - public string FileExtension + public override string FileExtension { get { return "XML"; } } - public void Execute(IExportExecuteContext context) + public override void Execute(IExportExecuteContext context) { var settings = new XmlWriterSettings { @@ -260,10 +255,5 @@ public void Execute(IExportExecuteContext context) writer.WriteEndDocument(); } } - - public void OnExecuted(IExportExecuteContext context) - { - // nothing to do - } } } diff --git a/src/Libraries/SmartStore.Services/DataExchange/Providers/ProductXlsxExportProvider.cs b/src/Libraries/SmartStore.Services/DataExchange/Providers/ProductXlsxExportProvider.cs index a433bf5c8d..3da13558c0 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Providers/ProductXlsxExportProvider.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Providers/ProductXlsxExportProvider.cs @@ -22,7 +22,7 @@ namespace SmartStore.Services.DataExchange.Providers [SystemName("Exports.SmartStoreProductXlsx")] [FriendlyName("SmartStore Excel product export")] [IsHidden(true)] - public class ProductXlsxExportProvider : IExportProvider + public class ProductXlsxExportProvider : ExportProviderBase { private readonly ILanguageService _languageService; private readonly IProductService _productService; @@ -165,22 +165,17 @@ public static string SystemName get { return "Exports.SmartStoreProductXlsx"; } } - public ExportConfigurationInfo ConfigurationInfo - { - get { return null; } - } - - public ExportEntityType EntityType + public override ExportEntityType EntityType { get { return ExportEntityType.Product; } } - public string FileExtension + public override string FileExtension { get { return "XLSX"; } } - public void Execute(IExportExecuteContext context) + public override void Execute(IExportExecuteContext context) { var path = context.FilePath; @@ -414,10 +409,5 @@ public void Execute(IExportExecuteContext context) // EPPLus had serious memory leak problems in V3. We enforce the garbage collector to release unused memory, it's not perfect, but better than nothing. GC.Collect(); } - - public void OnExecuted(IExportExecuteContext context) - { - // nothing to do - } } } diff --git a/src/Libraries/SmartStore.Services/DataExchange/Providers/ProductXmlExportProvider.cs b/src/Libraries/SmartStore.Services/DataExchange/Providers/ProductXmlExportProvider.cs index a0cc291bf1..e4154f4804 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Providers/ProductXmlExportProvider.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Providers/ProductXmlExportProvider.cs @@ -16,29 +16,24 @@ namespace SmartStore.Services.DataExchange.Providers [SystemName("Exports.SmartStoreProductXml")] [FriendlyName("SmartStore XML product export")] [IsHidden(true)] - public class ProductXmlExportProvider : IExportProvider + public class ProductXmlExportProvider : ExportProviderBase { public static string SystemName { get { return "Exports.SmartStoreProductXml"; } } - public ExportConfigurationInfo ConfigurationInfo - { - get { return null; } - } - - public ExportEntityType EntityType + public override ExportEntityType EntityType { get { return ExportEntityType.Product; } } - public string FileExtension + public override string FileExtension { get { return "XML"; } } - public void Execute(IExportExecuteContext context) + public override void Execute(IExportExecuteContext context) { var settings = new XmlWriterSettings { @@ -87,10 +82,5 @@ public void Execute(IExportExecuteContext context) writer.WriteEndDocument(); } } - - public void OnExecuted(IExportExecuteContext context) - { - // nothing to do - } } } diff --git a/src/Libraries/SmartStore.Services/DataExchange/Providers/SubscriberCsvExportProvider.cs b/src/Libraries/SmartStore.Services/DataExchange/Providers/SubscriberCsvExportProvider.cs index 2ca56f48f8..2a7e299b51 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Providers/SubscriberCsvExportProvider.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Providers/SubscriberCsvExportProvider.cs @@ -13,29 +13,24 @@ namespace SmartStore.Services.DataExchange.Providers [SystemName("Exports.SmartStoreNewsSubscriptionCsv")] [FriendlyName("SmartStore CSV newsletter subscription export")] [IsHidden(true)] - public class SubscriberCsvExportProvider : IExportProvider + public class SubscriberCsvExportProvider : ExportProviderBase { public static string SystemName { get { return "Exports.SmartStoreNewsSubscriptionCsv"; } } - public ExportConfigurationInfo ConfigurationInfo - { - get { return null; } - } - - public ExportEntityType EntityType + public override ExportEntityType EntityType { get { return ExportEntityType.NewsLetterSubscription; } } - public string FileExtension + public override string FileExtension { get { return "CSV"; } } - public void Execute(IExportExecuteContext context) + public override void Execute(IExportExecuteContext context) { var path = context.FilePath; @@ -73,10 +68,5 @@ public void Execute(IExportExecuteContext context) } } } - - public void OnExecuted(IExportExecuteContext context) - { - // nothing to do - } } } diff --git a/src/Libraries/SmartStore.Services/SmartStore.Services.csproj b/src/Libraries/SmartStore.Services/SmartStore.Services.csproj index f63d565765..7b4dc44e1e 100644 --- a/src/Libraries/SmartStore.Services/SmartStore.Services.csproj +++ b/src/Libraries/SmartStore.Services/SmartStore.Services.csproj @@ -171,6 +171,7 @@ + diff --git a/src/Plugins/SmartStore.GoogleMerchantCenter/Providers/GmcXmlExportProvider.cs b/src/Plugins/SmartStore.GoogleMerchantCenter/Providers/GmcXmlExportProvider.cs index 3f1dac0bd2..b1a68d4591 100644 --- a/src/Plugins/SmartStore.GoogleMerchantCenter/Providers/GmcXmlExportProvider.cs +++ b/src/Plugins/SmartStore.GoogleMerchantCenter/Providers/GmcXmlExportProvider.cs @@ -28,7 +28,7 @@ namespace SmartStore.GoogleMerchantCenter.Providers ExportFeatures.OffersBrandFallback, ExportFeatures.CanIncludeMainPicture, ExportFeatures.UsesSpecialPrice)] - public class GmcXmlExportProvider : IExportProvider + public class GmcXmlExportProvider : ExportProviderBase { private const string _googleNamespace = "http://base.google.com/ns/1.0"; @@ -132,7 +132,7 @@ public static string Unspecified get { return "__nospec__"; } } - public ExportConfigurationInfo ConfigurationInfo + public override ExportConfigurationInfo ConfigurationInfo { get { @@ -150,17 +150,12 @@ public ExportConfigurationInfo ConfigurationInfo } } - public ExportEntityType EntityType - { - get { return ExportEntityType.Product; } - } - - public string FileExtension + public override string FileExtension { get { return "XML"; } } - public void Execute(IExportExecuteContext context) + public override void Execute(IExportExecuteContext context) { var settings = new XmlWriterSettings { @@ -400,10 +395,5 @@ public void Execute(IExportExecuteContext context) writer.WriteEndDocument(); } } - - public void OnExecuted(IExportExecuteContext context) - { - // nothing to do - } } } \ No newline at end of file From adbce646e1586e37330c0e0178b23c9b7605e1a1 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Sun, 8 Nov 2015 11:40:45 +0100 Subject: [PATCH 002/626] ExportXmlHelper creates own XmlWriter --- .../ExportTask/ExportProfileTask.cs | 2 + .../DataExchange/ExportXmlHelper.cs | 39 ++- .../Providers/CategoryXmlExportProvider.cs | 49 +-- .../Providers/CustomerXmlExportProvider.cs | 27 +- .../ManufacturerXmlExportProvider.cs | 49 +-- .../Providers/OrderXmlExportProvider.cs | 308 +++++++++--------- .../Providers/ProductXmlExportProvider.cs | 27 +- .../Controllers/ExportController.cs | 3 +- 8 files changed, 238 insertions(+), 266 deletions(-) diff --git a/src/Libraries/SmartStore.Services/DataExchange/ExportTask/ExportProfileTask.cs b/src/Libraries/SmartStore.Services/DataExchange/ExportTask/ExportProfileTask.cs index 86c909fc27..1a52e264ea 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/ExportTask/ExportProfileTask.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/ExportTask/ExportProfileTask.cs @@ -132,6 +132,8 @@ private void InitDependencies(TaskExecutionContext context) _urlRecordService = context.Resolve>(); _genericAttributeService = context.Resolve>(); _subscriptionRepository = context.Resolve>>(); + + T = NullLocalizer.Instance; } public Localizer T { get; set; } diff --git a/src/Libraries/SmartStore.Services/DataExchange/ExportXmlHelper.cs b/src/Libraries/SmartStore.Services/DataExchange/ExportXmlHelper.cs index 8191f0d76e..e5837578d6 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/ExportXmlHelper.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/ExportXmlHelper.cs @@ -1,20 +1,53 @@ using System; using System.Globalization; +using System.IO; +using System.Text; using System.Xml; using SmartStore.Core.Domain.Catalog; using SmartStore.Core.Domain.DataExchange; namespace SmartStore.Services.DataExchange { - public class ExportXmlHelper + public class ExportXmlHelper : IDisposable { private XmlWriter _writer; private CultureInfo _culture; + private bool _doNotDispose; - public ExportXmlHelper(XmlWriter writer, CultureInfo culture) + public ExportXmlHelper(XmlWriter writer, bool doNotDispose = false, CultureInfo culture = null) { _writer = writer; - _culture = culture; + _doNotDispose = doNotDispose; + _culture = (culture == null ? CultureInfo.InvariantCulture : culture); + } + public ExportXmlHelper(Stream stream, XmlWriterSettings settings = null, CultureInfo culture = null) + { + if (settings == null) + { + settings = new XmlWriterSettings + { + Encoding = Encoding.UTF8, + CheckCharacters = false, + Indent = true, + IndentChars = "\t" + }; + } + + _writer = XmlWriter.Create(stream, settings); + _culture = (culture == null ? CultureInfo.InvariantCulture : culture); + } + + public XmlWriter Writer + { + get { return _writer; } + } + + public void Dispose() + { + if (_writer != null && !_doNotDispose) + { + _writer.Dispose(); + } } public void WriteLocalized(dynamic parentNode) diff --git a/src/Libraries/SmartStore.Services/DataExchange/Providers/CategoryXmlExportProvider.cs b/src/Libraries/SmartStore.Services/DataExchange/Providers/CategoryXmlExportProvider.cs index e473a28ad2..2b74231730 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Providers/CategoryXmlExportProvider.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Providers/CategoryXmlExportProvider.cs @@ -1,8 +1,5 @@ using System; -using System.Globalization; using System.IO; -using System.Text; -using System.Xml; using SmartStore.Core; using SmartStore.Core.Domain.DataExchange; using SmartStore.Core.Logging; @@ -35,26 +32,16 @@ public override string FileExtension public override void Execute(IExportExecuteContext context) { - var settings = new XmlWriterSettings - { - Encoding = Encoding.UTF8, - CheckCharacters = false, - Indent = true, - IndentChars = "\t" - }; - var path = context.FilePath; context.Log.Information("Creating file " + path); using (var stream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.ReadWrite)) - using (var writer = XmlWriter.Create(stream, settings)) + using (var helper = new ExportXmlHelper(stream)) { - var xmlHelper = new ExportXmlHelper(writer, CultureInfo.InvariantCulture); - - writer.WriteStartDocument(); - writer.WriteStartElement("Categories"); - writer.WriteAttributeString("Version", SmartStoreVersion.CurrentVersion); + helper.Writer.WriteStartDocument(); + helper.Writer.WriteStartElement("Categories"); + helper.Writer.WriteAttributeString("Version", SmartStoreVersion.CurrentVersion); while (context.Abort == ExportAbortion.None && context.Segmenter.ReadNextSegment()) { @@ -65,24 +52,24 @@ public override void Execute(IExportExecuteContext context) if (context.Abort != ExportAbortion.None) break; - writer.WriteStartElement("Category"); + helper.Writer.WriteStartElement("Category"); try { - xmlHelper.WriteCategory(category, null); + helper.WriteCategory(category, null); - writer.WriteStartElement("ProductCategories"); + helper.Writer.WriteStartElement("ProductCategories"); foreach (dynamic productCategory in category.ProductCategories) { - writer.WriteStartElement("ProductCategory"); - writer.Write("Id", ((int)productCategory.Id).ToString()); - writer.Write("ProductId", ((int)productCategory.ProductId).ToString()); - writer.Write("DisplayOrder", ((int)productCategory.DisplayOrder).ToString()); - writer.Write("IsFeaturedProduct", ((bool)productCategory.IsFeaturedProduct).ToString()); - writer.Write("CategoryId", ((int)productCategory.CategoryId).ToString()); - writer.WriteEndElement(); // ProductCategory + helper.Writer.WriteStartElement("ProductCategory"); + helper.Writer.Write("Id", ((int)productCategory.Id).ToString()); + helper.Writer.Write("ProductId", ((int)productCategory.ProductId).ToString()); + helper.Writer.Write("DisplayOrder", ((int)productCategory.DisplayOrder).ToString()); + helper.Writer.Write("IsFeaturedProduct", ((bool)productCategory.IsFeaturedProduct).ToString()); + helper.Writer.Write("CategoryId", ((int)productCategory.CategoryId).ToString()); + helper.Writer.WriteEndElement(); // ProductCategory } - writer.WriteEndElement(); // ProductCategories + helper.Writer.WriteEndElement(); // ProductCategories ++context.RecordsSucceeded; } @@ -91,12 +78,12 @@ public override void Execute(IExportExecuteContext context) context.RecordException(exc, (int)category.Id); } - writer.WriteEndElement(); // Category + helper.Writer.WriteEndElement(); // Category } } - writer.WriteEndElement(); // Categories - writer.WriteEndDocument(); + helper.Writer.WriteEndElement(); // Categories + helper.Writer.WriteEndDocument(); } } } diff --git a/src/Libraries/SmartStore.Services/DataExchange/Providers/CustomerXmlExportProvider.cs b/src/Libraries/SmartStore.Services/DataExchange/Providers/CustomerXmlExportProvider.cs index 93d9c4462b..4103b412a5 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Providers/CustomerXmlExportProvider.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Providers/CustomerXmlExportProvider.cs @@ -1,8 +1,5 @@ using System; -using System.Globalization; using System.IO; -using System.Text; -using System.Xml; using SmartStore.Core; using SmartStore.Core.Domain.DataExchange; using SmartStore.Core.Logging; @@ -35,26 +32,16 @@ public override string FileExtension public override void Execute(IExportExecuteContext context) { - var settings = new XmlWriterSettings - { - Encoding = Encoding.UTF8, - CheckCharacters = false, - Indent = true, - IndentChars = "\t" - }; - var path = context.FilePath; context.Log.Information("Creating file " + path); using (var stream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.ReadWrite)) - using (var writer = XmlWriter.Create(stream, settings)) + using (var helper = new ExportXmlHelper(stream)) { - var xmlHelper = new ExportXmlHelper(writer, CultureInfo.InvariantCulture); - - writer.WriteStartDocument(); - writer.WriteStartElement("Customers"); - writer.WriteAttributeString("Version", SmartStoreVersion.CurrentVersion); + helper.Writer.WriteStartDocument(); + helper.Writer.WriteStartElement("Customers"); + helper.Writer.WriteAttributeString("Version", SmartStoreVersion.CurrentVersion); while (context.Abort == ExportAbortion.None && context.Segmenter.ReadNextSegment()) { @@ -67,7 +54,7 @@ public override void Execute(IExportExecuteContext context) try { - xmlHelper.WriteCustomer(customer, "Customer"); + helper.WriteCustomer(customer, "Customer"); ++context.RecordsSucceeded; } @@ -78,8 +65,8 @@ public override void Execute(IExportExecuteContext context) } } - writer.WriteEndElement(); // Customers - writer.WriteEndDocument(); + helper.Writer.WriteEndElement(); // Customers + helper.Writer.WriteEndDocument(); } } } diff --git a/src/Libraries/SmartStore.Services/DataExchange/Providers/ManufacturerXmlExportProvider.cs b/src/Libraries/SmartStore.Services/DataExchange/Providers/ManufacturerXmlExportProvider.cs index 8d26a9ab4e..3c5d6afa53 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Providers/ManufacturerXmlExportProvider.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Providers/ManufacturerXmlExportProvider.cs @@ -1,8 +1,5 @@ using System; -using System.Globalization; using System.IO; -using System.Text; -using System.Xml; using SmartStore.Core; using SmartStore.Core.Domain.DataExchange; using SmartStore.Core.Logging; @@ -35,26 +32,16 @@ public override string FileExtension public override void Execute(IExportExecuteContext context) { - var settings = new XmlWriterSettings - { - Encoding = Encoding.UTF8, - CheckCharacters = false, - Indent = true, - IndentChars = "\t" - }; - var path = context.FilePath; context.Log.Information("Creating file " + path); using (var stream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.ReadWrite)) - using (var writer = XmlWriter.Create(stream, settings)) + using (var helper = new ExportXmlHelper(stream)) { - var xmlHelper = new ExportXmlHelper(writer, CultureInfo.InvariantCulture); - - writer.WriteStartDocument(); - writer.WriteStartElement("Manufacturers"); - writer.WriteAttributeString("Version", SmartStoreVersion.CurrentVersion); + helper.Writer.WriteStartDocument(); + helper.Writer.WriteStartElement("Manufacturers"); + helper.Writer.WriteAttributeString("Version", SmartStoreVersion.CurrentVersion); while (context.Abort == ExportAbortion.None && context.Segmenter.ReadNextSegment()) { @@ -65,24 +52,24 @@ public override void Execute(IExportExecuteContext context) if (context.Abort != ExportAbortion.None) break; - writer.WriteStartElement("Manufacturer"); + helper.Writer.WriteStartElement("Manufacturer"); try { - xmlHelper.WriteManufacturer(manufacturer, null); + helper.WriteManufacturer(manufacturer, null); - writer.WriteStartElement("ProductManufacturers"); + helper.Writer.WriteStartElement("ProductManufacturers"); foreach (dynamic productManu in manufacturer.ProductManufacturers) { - writer.WriteStartElement("ProductManufacturer"); - writer.Write("Id", ((int)productManu.Id).ToString()); - writer.Write("ProductId", ((int)productManu.ProductId).ToString()); - writer.Write("DisplayOrder", ((int)productManu.DisplayOrder).ToString()); - writer.Write("IsFeaturedProduct", ((bool)productManu.IsFeaturedProduct).ToString()); - writer.Write("ManufacturerId", ((int)productManu.ManufacturerId).ToString()); - writer.WriteEndElement(); // ProductManufacturer + helper.Writer.WriteStartElement("ProductManufacturer"); + helper.Writer.Write("Id", ((int)productManu.Id).ToString()); + helper.Writer.Write("ProductId", ((int)productManu.ProductId).ToString()); + helper.Writer.Write("DisplayOrder", ((int)productManu.DisplayOrder).ToString()); + helper.Writer.Write("IsFeaturedProduct", ((bool)productManu.IsFeaturedProduct).ToString()); + helper.Writer.Write("ManufacturerId", ((int)productManu.ManufacturerId).ToString()); + helper.Writer.WriteEndElement(); // ProductManufacturer } - writer.WriteEndElement(); // ProductManufacturers + helper.Writer.WriteEndElement(); // ProductManufacturers ++context.RecordsSucceeded; } @@ -91,12 +78,12 @@ public override void Execute(IExportExecuteContext context) context.RecordException(exc, (int)manufacturer.Id); } - writer.WriteEndElement(); // Manufacturer + helper.Writer.WriteEndElement(); // Manufacturer } } - writer.WriteEndElement(); // Manufacturers - writer.WriteEndDocument(); + helper.Writer.WriteEndElement(); // Manufacturers + helper.Writer.WriteEndDocument(); } } } diff --git a/src/Libraries/SmartStore.Services/DataExchange/Providers/OrderXmlExportProvider.cs b/src/Libraries/SmartStore.Services/DataExchange/Providers/OrderXmlExportProvider.cs index 15d347847f..470155603a 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Providers/OrderXmlExportProvider.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Providers/OrderXmlExportProvider.cs @@ -1,8 +1,6 @@ using System; using System.Globalization; using System.IO; -using System.Text; -using System.Xml; using SmartStore.Core; using SmartStore.Core.Domain.DataExchange; using SmartStore.Core.Logging; @@ -35,27 +33,17 @@ public override string FileExtension public override void Execute(IExportExecuteContext context) { - var settings = new XmlWriterSettings - { - Encoding = Encoding.UTF8, - CheckCharacters = false, - Indent = true, - IndentChars = "\t" - }; - var path = context.FilePath; var invariantCulture = CultureInfo.InvariantCulture; context.Log.Information("Creating file " + path); using (var stream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.ReadWrite)) - using (var writer = XmlWriter.Create(stream, settings)) + using (var helper = new ExportXmlHelper(stream)) { - var xmlHelper = new ExportXmlHelper(writer, invariantCulture); - - writer.WriteStartDocument(); - writer.WriteStartElement("Orders"); - writer.WriteAttributeString("Version", SmartStoreVersion.CurrentVersion); + helper.Writer.WriteStartDocument(); + helper.Writer.WriteStartElement("Orders"); + helper.Writer.WriteAttributeString("Version", SmartStoreVersion.CurrentVersion); while (context.Abort == ExportAbortion.None && context.Segmenter.ReadNextSegment()) { @@ -66,7 +54,7 @@ public override void Execute(IExportExecuteContext context) if (context.Abort != ExportAbortion.None) break; - writer.WriteStartElement("Order"); + helper.Writer.WriteStartElement("Order"); try { @@ -75,170 +63,170 @@ public override void Execute(IExportExecuteContext context) DateTime? paidDateUtc = order.PaidDateUtc; int? rewardPointsRemaining = order.RewardPointsRemaining; - writer.Write("Id", ((int)order.Id).ToString()); - writer.Write("OrderNumber", (string)order.OrderNumber); - writer.Write("OrderGuid", ((Guid)order.OrderGuid).ToString()); - writer.Write("StoreId", ((int)order.StoreId).ToString()); - writer.Write("CustomerId", ((int)order.CustomerId).ToString()); - writer.Write("BillingAddressId", ((int)order.BillingAddressId).ToString()); - writer.Write("ShippingAddressId", shippingAddressId.HasValue ? shippingAddressId.Value.ToString() : ""); - writer.Write("OrderStatusId", ((int)order.OrderStatusId).ToString()); - writer.Write("ShippingStatusId", ((int)order.ShippingStatusId).ToString()); - writer.Write("PaymentStatusId", ((int)order.PaymentStatusId).ToString()); - writer.Write("PaymentMethodSystemName", (string)order.PaymentMethodSystemName); - writer.Write("CustomerCurrencyCode", (string)order.CustomerCurrencyCode); - writer.Write("CurrencyRate", ((decimal)order.CurrencyRate).ToString(invariantCulture)); - writer.Write("CustomerTaxDisplayTypeId", ((int)order.CustomerTaxDisplayTypeId).ToString()); - writer.Write("VatNumber", (string)order.VatNumber); - writer.Write("OrderSubtotalInclTax", ((decimal)order.OrderSubtotalInclTax).ToString(invariantCulture)); - writer.Write("OrderSubtotalExclTax", ((decimal)order.OrderSubtotalExclTax).ToString(invariantCulture)); - writer.Write("OrderSubTotalDiscountInclTax", ((decimal)order.OrderSubTotalDiscountInclTax).ToString(invariantCulture)); - writer.Write("OrderSubTotalDiscountExclTax", ((decimal)order.OrderSubTotalDiscountExclTax).ToString(invariantCulture)); - writer.Write("OrderShippingInclTax", ((decimal)order.OrderShippingInclTax).ToString(invariantCulture)); - writer.Write("OrderShippingExclTax", ((decimal)order.OrderShippingExclTax).ToString(invariantCulture)); - writer.Write("OrderShippingTaxRate", ((decimal)order.OrderShippingTaxRate).ToString(invariantCulture)); - writer.Write("PaymentMethodAdditionalFeeInclTax", ((decimal)order.PaymentMethodAdditionalFeeInclTax).ToString(invariantCulture)); - writer.Write("PaymentMethodAdditionalFeeExclTax", ((decimal)order.PaymentMethodAdditionalFeeExclTax).ToString(invariantCulture)); - writer.Write("PaymentMethodAdditionalFeeTaxRate", ((decimal)order.PaymentMethodAdditionalFeeTaxRate).ToString(invariantCulture)); - writer.Write("TaxRates", (string)order.TaxRates); - writer.Write("OrderTax", ((decimal)order.OrderTax).ToString(invariantCulture)); - writer.Write("OrderDiscount", ((decimal)order.OrderDiscount).ToString(invariantCulture)); - writer.Write("OrderTotal", ((decimal)order.OrderTotal).ToString(invariantCulture)); - writer.Write("RefundedAmount", ((decimal)order.RefundedAmount).ToString(invariantCulture)); - writer.Write("RewardPointsWereAdded", ((bool)order.RewardPointsWereAdded).ToString()); - writer.Write("CheckoutAttributeDescription", (string)order.CheckoutAttributeDescription); - writer.Write("CheckoutAttributesXml", (string)order.CheckoutAttributesXml); - writer.Write("CustomerLanguageId", ((int)order.CustomerLanguageId).ToString()); - writer.Write("AffiliateId", ((int)order.AffiliateId).ToString()); - writer.Write("CustomerIp", (string)order.CustomerIp); - writer.Write("AllowStoringCreditCardNumber", ((bool)order.AllowStoringCreditCardNumber).ToString()); - writer.Write("CardType", (string)order.CardType); - writer.Write("CardName", (string)order.CardName); - writer.Write("CardNumber", (string)order.CardNumber); - writer.Write("MaskedCreditCardNumber", (string)order.MaskedCreditCardNumber); - writer.Write("CardCvv2", (string)order.CardCvv2); - writer.Write("CardExpirationMonth", (string)order.CardExpirationMonth); - writer.Write("CardExpirationYear", (string)order.CardExpirationYear); - writer.Write("AllowStoringDirectDebit", ((bool)order.AllowStoringDirectDebit).ToString()); - writer.Write("DirectDebitAccountHolder", (string)order.DirectDebitAccountHolder); - writer.Write("DirectDebitAccountNumber", (string)order.DirectDebitAccountNumber); - writer.Write("DirectDebitBankCode", (string)order.DirectDebitBankCode); - writer.Write("DirectDebitBankName", (string)order.DirectDebitBankName); - writer.Write("DirectDebitBIC", (string)order.DirectDebitBIC); - writer.Write("DirectDebitCountry", (string)order.DirectDebitCountry); - writer.Write("DirectDebitIban", (string)order.DirectDebitIban); - writer.Write("CustomerOrderComment", (string)order.CustomerOrderComment); - writer.Write("AuthorizationTransactionId", (string)order.AuthorizationTransactionId); - writer.Write("AuthorizationTransactionCode", (string)order.AuthorizationTransactionCode); - writer.Write("AuthorizationTransactionResult", (string)order.AuthorizationTransactionResult); - writer.Write("CaptureTransactionId", (string)order.CaptureTransactionId); - writer.Write("CaptureTransactionResult", (string)order.CaptureTransactionResult); - writer.Write("SubscriptionTransactionId", (string)order.SubscriptionTransactionId); - writer.Write("PurchaseOrderNumber", (string)order.PurchaseOrderNumber); - writer.Write("PaidDateUtc", paidDateUtc.HasValue ? paidDateUtc.Value.ToString(invariantCulture) : ""); - writer.Write("ShippingMethod", (string)order.ShippingMethod); - writer.Write("ShippingRateComputationMethodSystemName", (string)order.ShippingRateComputationMethodSystemName); - writer.Write("Deleted", ((bool)order.Deleted).ToString()); - writer.Write("CreatedOnUtc", ((DateTime)order.CreatedOnUtc).ToString(invariantCulture)); - writer.Write("UpdatedOnUtc", ((DateTime)order.UpdatedOnUtc).ToString(invariantCulture)); - writer.Write("RewardPointsRemaining", rewardPointsRemaining.HasValue ? rewardPointsRemaining.Value.ToString() : ""); - writer.Write("HasNewPaymentNotification", ((bool)order.HasNewPaymentNotification).ToString()); - writer.Write("OrderStatus", (string)order.OrderStatus); - writer.Write("PaymentStatus", (string)order.PaymentStatus); - writer.Write("ShippingStatus", (string)order.ShippingStatus); - - xmlHelper.WriteCustomer(order.Customer, "Customer"); - - xmlHelper.WriteAddress(order.BillingAddress, "BillingAddress"); - xmlHelper.WriteAddress(order.ShippingAddress, "ShippingAddress"); + helper.Writer.Write("Id", ((int)order.Id).ToString()); + helper.Writer.Write("OrderNumber", (string)order.OrderNumber); + helper.Writer.Write("OrderGuid", ((Guid)order.OrderGuid).ToString()); + helper.Writer.Write("StoreId", ((int)order.StoreId).ToString()); + helper.Writer.Write("CustomerId", ((int)order.CustomerId).ToString()); + helper.Writer.Write("BillingAddressId", ((int)order.BillingAddressId).ToString()); + helper.Writer.Write("ShippingAddressId", shippingAddressId.HasValue ? shippingAddressId.Value.ToString() : ""); + helper.Writer.Write("OrderStatusId", ((int)order.OrderStatusId).ToString()); + helper.Writer.Write("ShippingStatusId", ((int)order.ShippingStatusId).ToString()); + helper.Writer.Write("PaymentStatusId", ((int)order.PaymentStatusId).ToString()); + helper.Writer.Write("PaymentMethodSystemName", (string)order.PaymentMethodSystemName); + helper.Writer.Write("CustomerCurrencyCode", (string)order.CustomerCurrencyCode); + helper.Writer.Write("CurrencyRate", ((decimal)order.CurrencyRate).ToString(invariantCulture)); + helper.Writer.Write("CustomerTaxDisplayTypeId", ((int)order.CustomerTaxDisplayTypeId).ToString()); + helper.Writer.Write("VatNumber", (string)order.VatNumber); + helper.Writer.Write("OrderSubtotalInclTax", ((decimal)order.OrderSubtotalInclTax).ToString(invariantCulture)); + helper.Writer.Write("OrderSubtotalExclTax", ((decimal)order.OrderSubtotalExclTax).ToString(invariantCulture)); + helper.Writer.Write("OrderSubTotalDiscountInclTax", ((decimal)order.OrderSubTotalDiscountInclTax).ToString(invariantCulture)); + helper.Writer.Write("OrderSubTotalDiscountExclTax", ((decimal)order.OrderSubTotalDiscountExclTax).ToString(invariantCulture)); + helper.Writer.Write("OrderShippingInclTax", ((decimal)order.OrderShippingInclTax).ToString(invariantCulture)); + helper.Writer.Write("OrderShippingExclTax", ((decimal)order.OrderShippingExclTax).ToString(invariantCulture)); + helper.Writer.Write("OrderShippingTaxRate", ((decimal)order.OrderShippingTaxRate).ToString(invariantCulture)); + helper.Writer.Write("PaymentMethodAdditionalFeeInclTax", ((decimal)order.PaymentMethodAdditionalFeeInclTax).ToString(invariantCulture)); + helper.Writer.Write("PaymentMethodAdditionalFeeExclTax", ((decimal)order.PaymentMethodAdditionalFeeExclTax).ToString(invariantCulture)); + helper.Writer.Write("PaymentMethodAdditionalFeeTaxRate", ((decimal)order.PaymentMethodAdditionalFeeTaxRate).ToString(invariantCulture)); + helper.Writer.Write("TaxRates", (string)order.TaxRates); + helper.Writer.Write("OrderTax", ((decimal)order.OrderTax).ToString(invariantCulture)); + helper.Writer.Write("OrderDiscount", ((decimal)order.OrderDiscount).ToString(invariantCulture)); + helper.Writer.Write("OrderTotal", ((decimal)order.OrderTotal).ToString(invariantCulture)); + helper.Writer.Write("RefundedAmount", ((decimal)order.RefundedAmount).ToString(invariantCulture)); + helper.Writer.Write("RewardPointsWereAdded", ((bool)order.RewardPointsWereAdded).ToString()); + helper.Writer.Write("CheckoutAttributeDescription", (string)order.CheckoutAttributeDescription); + helper.Writer.Write("CheckoutAttributesXml", (string)order.CheckoutAttributesXml); + helper.Writer.Write("CustomerLanguageId", ((int)order.CustomerLanguageId).ToString()); + helper.Writer.Write("AffiliateId", ((int)order.AffiliateId).ToString()); + helper.Writer.Write("CustomerIp", (string)order.CustomerIp); + helper.Writer.Write("AllowStoringCreditCardNumber", ((bool)order.AllowStoringCreditCardNumber).ToString()); + helper.Writer.Write("CardType", (string)order.CardType); + helper.Writer.Write("CardName", (string)order.CardName); + helper.Writer.Write("CardNumber", (string)order.CardNumber); + helper.Writer.Write("MaskedCreditCardNumber", (string)order.MaskedCreditCardNumber); + helper.Writer.Write("CardCvv2", (string)order.CardCvv2); + helper.Writer.Write("CardExpirationMonth", (string)order.CardExpirationMonth); + helper.Writer.Write("CardExpirationYear", (string)order.CardExpirationYear); + helper.Writer.Write("AllowStoringDirectDebit", ((bool)order.AllowStoringDirectDebit).ToString()); + helper.Writer.Write("DirectDebitAccountHolder", (string)order.DirectDebitAccountHolder); + helper.Writer.Write("DirectDebitAccountNumber", (string)order.DirectDebitAccountNumber); + helper.Writer.Write("DirectDebitBankCode", (string)order.DirectDebitBankCode); + helper.Writer.Write("DirectDebitBankName", (string)order.DirectDebitBankName); + helper.Writer.Write("DirectDebitBIC", (string)order.DirectDebitBIC); + helper.Writer.Write("DirectDebitCountry", (string)order.DirectDebitCountry); + helper.Writer.Write("DirectDebitIban", (string)order.DirectDebitIban); + helper.Writer.Write("CustomerOrderComment", (string)order.CustomerOrderComment); + helper.Writer.Write("AuthorizationTransactionId", (string)order.AuthorizationTransactionId); + helper.Writer.Write("AuthorizationTransactionCode", (string)order.AuthorizationTransactionCode); + helper.Writer.Write("AuthorizationTransactionResult", (string)order.AuthorizationTransactionResult); + helper.Writer.Write("CaptureTransactionId", (string)order.CaptureTransactionId); + helper.Writer.Write("CaptureTransactionResult", (string)order.CaptureTransactionResult); + helper.Writer.Write("SubscriptionTransactionId", (string)order.SubscriptionTransactionId); + helper.Writer.Write("PurchaseOrderNumber", (string)order.PurchaseOrderNumber); + helper.Writer.Write("PaidDateUtc", paidDateUtc.HasValue ? paidDateUtc.Value.ToString(invariantCulture) : ""); + helper.Writer.Write("ShippingMethod", (string)order.ShippingMethod); + helper.Writer.Write("ShippingRateComputationMethodSystemName", (string)order.ShippingRateComputationMethodSystemName); + helper.Writer.Write("Deleted", ((bool)order.Deleted).ToString()); + helper.Writer.Write("CreatedOnUtc", ((DateTime)order.CreatedOnUtc).ToString(invariantCulture)); + helper.Writer.Write("UpdatedOnUtc", ((DateTime)order.UpdatedOnUtc).ToString(invariantCulture)); + helper.Writer.Write("RewardPointsRemaining", rewardPointsRemaining.HasValue ? rewardPointsRemaining.Value.ToString() : ""); + helper.Writer.Write("HasNewPaymentNotification", ((bool)order.HasNewPaymentNotification).ToString()); + helper.Writer.Write("OrderStatus", (string)order.OrderStatus); + helper.Writer.Write("PaymentStatus", (string)order.PaymentStatus); + helper.Writer.Write("ShippingStatus", (string)order.ShippingStatus); + + helper.WriteCustomer(order.Customer, "Customer"); + + helper.WriteAddress(order.BillingAddress, "BillingAddress"); + helper.WriteAddress(order.ShippingAddress, "ShippingAddress"); if (store != null) { - writer.WriteStartElement("Store"); - writer.Write("Id", ((int)store.Id).ToString()); - writer.Write("Name", (string)store.Name); - writer.Write("Url", (string)store.Url); - writer.Write("SslEnabled", ((bool)store.SslEnabled).ToString()); - writer.Write("SecureUrl", (string)store.SecureUrl); - writer.Write("Hosts", (string)store.Hosts); - writer.Write("LogoPictureId", ((int)store.LogoPictureId).ToString()); - writer.Write("DisplayOrder", ((int)store.DisplayOrder).ToString()); - writer.Write("HtmlBodyId", (string)store.HtmlBodyId); - writer.Write("ContentDeliveryNetwork", (string)store.ContentDeliveryNetwork); - writer.Write("PrimaryStoreCurrencyId", ((int)store.PrimaryStoreCurrencyId).ToString()); - writer.Write("PrimaryExchangeRateCurrencyId", ((int)store.PrimaryExchangeRateCurrencyId).ToString()); - - xmlHelper.WriteCurrency(store.PrimaryStoreCurrency, "PrimaryStoreCurrency"); - xmlHelper.WriteCurrency(store.PrimaryExchangeRateCurrency, "PrimaryExchangeRateCurrency"); - - writer.WriteEndElement(); // Store + helper.Writer.WriteStartElement("Store"); + helper.Writer.Write("Id", ((int)store.Id).ToString()); + helper.Writer.Write("Name", (string)store.Name); + helper.Writer.Write("Url", (string)store.Url); + helper.Writer.Write("SslEnabled", ((bool)store.SslEnabled).ToString()); + helper.Writer.Write("SecureUrl", (string)store.SecureUrl); + helper.Writer.Write("Hosts", (string)store.Hosts); + helper.Writer.Write("LogoPictureId", ((int)store.LogoPictureId).ToString()); + helper.Writer.Write("DisplayOrder", ((int)store.DisplayOrder).ToString()); + helper.Writer.Write("HtmlBodyId", (string)store.HtmlBodyId); + helper.Writer.Write("ContentDeliveryNetwork", (string)store.ContentDeliveryNetwork); + helper.Writer.Write("PrimaryStoreCurrencyId", ((int)store.PrimaryStoreCurrencyId).ToString()); + helper.Writer.Write("PrimaryExchangeRateCurrencyId", ((int)store.PrimaryExchangeRateCurrencyId).ToString()); + + helper.WriteCurrency(store.PrimaryStoreCurrency, "PrimaryStoreCurrency"); + helper.WriteCurrency(store.PrimaryExchangeRateCurrency, "PrimaryExchangeRateCurrency"); + + helper.Writer.WriteEndElement(); // Store } - writer.WriteStartElement("OrderItems"); + helper.Writer.WriteStartElement("OrderItems"); foreach (dynamic orderItem in order.OrderItems) { int? licenseDownloadId = orderItem.LicenseDownloadId; decimal? itemWeight = orderItem.ItemWeight; - writer.WriteStartElement("OrderItem"); - writer.Write("Id", ((int)orderItem.Id).ToString()); - writer.Write("OrderItemGuid", ((Guid)orderItem.OrderItemGuid).ToString()); - writer.Write("OrderId", ((int)orderItem.OrderId).ToString()); - writer.Write("ProductId", ((int)orderItem.ProductId).ToString()); - writer.Write("Quantity", ((int)orderItem.Quantity).ToString()); - writer.Write("UnitPriceInclTax", ((decimal)orderItem.UnitPriceInclTax).ToString(invariantCulture)); - writer.Write("UnitPriceExclTax", ((decimal)orderItem.UnitPriceExclTax).ToString(invariantCulture)); - writer.Write("PriceInclTax", ((decimal)orderItem.PriceInclTax).ToString(invariantCulture)); - writer.Write("PriceExclTax", ((decimal)orderItem.PriceExclTax).ToString(invariantCulture)); - writer.Write("TaxRate", ((decimal)orderItem.TaxRate).ToString(invariantCulture)); - writer.Write("DiscountAmountInclTax", ((decimal)orderItem.DiscountAmountInclTax).ToString(invariantCulture)); - writer.Write("DiscountAmountExclTax", ((decimal)orderItem.DiscountAmountExclTax).ToString(invariantCulture)); - writer.Write("AttributeDescription", (string)orderItem.AttributeDescription); - writer.Write("AttributesXml", (string)orderItem.AttributesXml); - writer.Write("DownloadCount", ((int)orderItem.DownloadCount).ToString()); - writer.Write("IsDownloadActivated", ((bool)orderItem.IsDownloadActivated).ToString()); - writer.Write("LicenseDownloadId", licenseDownloadId.HasValue ? licenseDownloadId.Value.ToString() : ""); - writer.Write("ItemWeight", itemWeight.HasValue ? itemWeight.Value.ToString(invariantCulture) : ""); - writer.Write("BundleData", (string)orderItem.BundleData); - writer.Write("ProductCost", ((decimal)orderItem.ProductCost).ToString(invariantCulture)); - - xmlHelper.WriteProduct(orderItem.Product, "Product"); - - writer.WriteEndElement(); // OrderItem + helper.Writer.WriteStartElement("OrderItem"); + helper.Writer.Write("Id", ((int)orderItem.Id).ToString()); + helper.Writer.Write("OrderItemGuid", ((Guid)orderItem.OrderItemGuid).ToString()); + helper.Writer.Write("OrderId", ((int)orderItem.OrderId).ToString()); + helper.Writer.Write("ProductId", ((int)orderItem.ProductId).ToString()); + helper.Writer.Write("Quantity", ((int)orderItem.Quantity).ToString()); + helper.Writer.Write("UnitPriceInclTax", ((decimal)orderItem.UnitPriceInclTax).ToString(invariantCulture)); + helper.Writer.Write("UnitPriceExclTax", ((decimal)orderItem.UnitPriceExclTax).ToString(invariantCulture)); + helper.Writer.Write("PriceInclTax", ((decimal)orderItem.PriceInclTax).ToString(invariantCulture)); + helper.Writer.Write("PriceExclTax", ((decimal)orderItem.PriceExclTax).ToString(invariantCulture)); + helper.Writer.Write("TaxRate", ((decimal)orderItem.TaxRate).ToString(invariantCulture)); + helper.Writer.Write("DiscountAmountInclTax", ((decimal)orderItem.DiscountAmountInclTax).ToString(invariantCulture)); + helper.Writer.Write("DiscountAmountExclTax", ((decimal)orderItem.DiscountAmountExclTax).ToString(invariantCulture)); + helper.Writer.Write("AttributeDescription", (string)orderItem.AttributeDescription); + helper.Writer.Write("AttributesXml", (string)orderItem.AttributesXml); + helper.Writer.Write("DownloadCount", ((int)orderItem.DownloadCount).ToString()); + helper.Writer.Write("IsDownloadActivated", ((bool)orderItem.IsDownloadActivated).ToString()); + helper.Writer.Write("LicenseDownloadId", licenseDownloadId.HasValue ? licenseDownloadId.Value.ToString() : ""); + helper.Writer.Write("ItemWeight", itemWeight.HasValue ? itemWeight.Value.ToString(invariantCulture) : ""); + helper.Writer.Write("BundleData", (string)orderItem.BundleData); + helper.Writer.Write("ProductCost", ((decimal)orderItem.ProductCost).ToString(invariantCulture)); + + helper.WriteProduct(orderItem.Product, "Product"); + + helper.Writer.WriteEndElement(); // OrderItem } - writer.WriteEndElement(); // OrderItems + helper.Writer.WriteEndElement(); // OrderItems - writer.WriteStartElement("Shipments"); + helper.Writer.WriteStartElement("Shipments"); foreach (dynamic shipment in order.Shipments) { decimal? totalWeight = shipment.TotalWeight; DateTime? shippedDateUtc = shipment.ShippedDateUtc; DateTime? deliveryDateUtc = shipment.DeliveryDateUtc; - writer.WriteStartElement("Shipment"); - writer.Write("Id", ((int)shipment.Id).ToString()); - writer.Write("OrderId", ((int)shipment.OrderId).ToString()); - writer.Write("TrackingNumber", (string)shipment.TrackingNumber); - writer.Write("TotalWeight", totalWeight.HasValue ? totalWeight.Value.ToString(invariantCulture) : ""); - writer.Write("ShippedDateUtc", shippedDateUtc.HasValue ? shippedDateUtc.Value.ToString(invariantCulture) : ""); - writer.Write("DeliveryDateUtc", deliveryDateUtc.HasValue ? deliveryDateUtc.Value.ToString(invariantCulture) : ""); - writer.Write("CreatedOnUtc", ((DateTime)shipment.CreatedOnUtc).ToString(invariantCulture)); + helper.Writer.WriteStartElement("Shipment"); + helper.Writer.Write("Id", ((int)shipment.Id).ToString()); + helper.Writer.Write("OrderId", ((int)shipment.OrderId).ToString()); + helper.Writer.Write("TrackingNumber", (string)shipment.TrackingNumber); + helper.Writer.Write("TotalWeight", totalWeight.HasValue ? totalWeight.Value.ToString(invariantCulture) : ""); + helper.Writer.Write("ShippedDateUtc", shippedDateUtc.HasValue ? shippedDateUtc.Value.ToString(invariantCulture) : ""); + helper.Writer.Write("DeliveryDateUtc", deliveryDateUtc.HasValue ? deliveryDateUtc.Value.ToString(invariantCulture) : ""); + helper.Writer.Write("CreatedOnUtc", ((DateTime)shipment.CreatedOnUtc).ToString(invariantCulture)); - writer.WriteStartElement("ShipmentItems"); + helper.Writer.WriteStartElement("ShipmentItems"); foreach (dynamic shipmentItem in shipment.ShipmentItems) { - writer.WriteStartElement("ShipmentItem"); - writer.Write("Id", ((int)shipmentItem.Id).ToString()); - writer.Write("ShipmentId", ((int)shipmentItem.ShipmentId).ToString()); - writer.Write("OrderItemId", ((int)shipmentItem.OrderItemId).ToString()); - writer.Write("Quantity", ((int)shipmentItem.Quantity).ToString()); - writer.WriteEndElement(); // ShipmentItem + helper.Writer.WriteStartElement("ShipmentItem"); + helper.Writer.Write("Id", ((int)shipmentItem.Id).ToString()); + helper.Writer.Write("ShipmentId", ((int)shipmentItem.ShipmentId).ToString()); + helper.Writer.Write("OrderItemId", ((int)shipmentItem.OrderItemId).ToString()); + helper.Writer.Write("Quantity", ((int)shipmentItem.Quantity).ToString()); + helper.Writer.WriteEndElement(); // ShipmentItem } - writer.WriteEndElement(); // ShipmentItems + helper.Writer.WriteEndElement(); // ShipmentItems - writer.WriteEndElement(); // Shipment + helper.Writer.WriteEndElement(); // Shipment } - writer.WriteEndElement(); // Shipments + helper.Writer.WriteEndElement(); // Shipments ++context.RecordsSucceeded; } @@ -247,12 +235,12 @@ public override void Execute(IExportExecuteContext context) context.RecordException(exc, (int)order.Id); } - writer.WriteEndElement(); // Order + helper.Writer.WriteEndElement(); // Order } } - writer.WriteEndElement(); // Orders - writer.WriteEndDocument(); + helper.Writer.WriteEndElement(); // Orders + helper.Writer.WriteEndDocument(); } } } diff --git a/src/Libraries/SmartStore.Services/DataExchange/Providers/ProductXmlExportProvider.cs b/src/Libraries/SmartStore.Services/DataExchange/Providers/ProductXmlExportProvider.cs index e4154f4804..a3480bdb3a 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Providers/ProductXmlExportProvider.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Providers/ProductXmlExportProvider.cs @@ -1,8 +1,5 @@ using System; -using System.Globalization; using System.IO; -using System.Text; -using System.Xml; using SmartStore.Core; using SmartStore.Core.Domain.DataExchange; using SmartStore.Core.Logging; @@ -35,26 +32,16 @@ public override string FileExtension public override void Execute(IExportExecuteContext context) { - var settings = new XmlWriterSettings - { - Encoding = Encoding.UTF8, - CheckCharacters = false, - Indent = true, - IndentChars = "\t" - }; - var path = context.FilePath; context.Log.Information("Creating file " + path); using (var stream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.ReadWrite)) - using (var writer = XmlWriter.Create(stream, settings)) + using (var helper = new ExportXmlHelper(stream)) { - var xmlHelper = new ExportXmlHelper(writer, CultureInfo.InvariantCulture); - - writer.WriteStartDocument(); - writer.WriteStartElement("Products"); - writer.WriteAttributeString("Version", SmartStoreVersion.CurrentVersion); + helper.Writer.WriteStartDocument(); + helper.Writer.WriteStartElement("Products"); + helper.Writer.WriteAttributeString("Version", SmartStoreVersion.CurrentVersion); while (context.Abort == ExportAbortion.None && context.Segmenter.ReadNextSegment()) { @@ -67,7 +54,7 @@ public override void Execute(IExportExecuteContext context) try { - xmlHelper.WriteProduct(product, "Product"); + helper.WriteProduct(product, "Product"); ++context.RecordsSucceeded; } @@ -78,8 +65,8 @@ public override void Execute(IExportExecuteContext context) } } - writer.WriteEndElement(); // Products - writer.WriteEndDocument(); + helper.Writer.WriteEndElement(); // Products + helper.Writer.WriteEndDocument(); } } } diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs index 984f3641a1..29c4c040b9 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs @@ -3,6 +3,7 @@ using System.IO; using System.Linq; using System.Net.Mime; +using System.Text; using System.Web; using System.Web.Mvc; using Autofac; @@ -878,7 +879,7 @@ public ActionResult DownloadLogFile(int id) var path = profile.GetExportLogFilePath(); var stream = new FileStream(path, FileMode.Open); - var result = new FileStreamResult(stream, MediaTypeNames.Text.Plain); + var result = new FileStreamResult(stream, "text/plain; charset=utf-8"); result.FileDownloadName = profile.Name.ToValidFileName() + "-log.txt"; return result; From 451dd5e9460a20fc8e9e010bcf9bce4a510748a2 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Sun, 8 Nov 2015 18:58:53 +0100 Subject: [PATCH 003/626] Export framework rather than provider should create export data files --- .../Extensions/XmlWriterExtensions.cs | 10 -- .../DataExchange/ExportExecuteContext.cs | 54 ++++++-- .../ExportTask/ExportProfileTask.cs | 122 +++++++++++++----- .../DataExchange/ExportXmlHelper.cs | 16 ++- .../Providers/CategoryXmlExportProvider.cs | 9 +- .../Providers/CustomerXlsxExportProvider.cs | 8 +- .../Providers/CustomerXmlExportProvider.cs | 9 +- .../ManufacturerXmlExportProvider.cs | 9 +- .../Providers/OrderXlsxExportProvider.cs | 9 +- .../Providers/OrderXmlExportProvider.cs | 8 +- .../Providers/ProductXlsxExportProvider.cs | 9 +- .../Providers/ProductXmlExportProvider.cs | 9 +- .../Providers/SubscriberCsvExportProvider.cs | 8 +- .../Providers/GmcXmlExportProvider.cs | 14 +- 14 files changed, 153 insertions(+), 141 deletions(-) diff --git a/src/Libraries/SmartStore.Core/Extensions/XmlWriterExtensions.cs b/src/Libraries/SmartStore.Core/Extensions/XmlWriterExtensions.cs index 5ead943146..ca4e1c2c71 100644 --- a/src/Libraries/SmartStore.Core/Extensions/XmlWriterExtensions.cs +++ b/src/Libraries/SmartStore.Core/Extensions/XmlWriterExtensions.cs @@ -21,16 +21,6 @@ public static void WriteCData(this XmlWriter writer, string name, string value, } } - public static void WriteNode(this XmlWriter writer, string name, Action content) - { - if (name.HasValue() && content != null) - { - writer.WriteStartElement(name); - content(); - writer.WriteEndElement(); - } - } - /// /// Created a simple or CData node element /// diff --git a/src/Libraries/SmartStore.Services/DataExchange/ExportExecuteContext.cs b/src/Libraries/SmartStore.Services/DataExchange/ExportExecuteContext.cs index 17ae53a8bf..d4a6286570 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/ExportExecuteContext.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/ExportExecuteContext.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.IO; using System.Threading; using SmartStore.Core.Domain.DataExchange; using SmartStore.Core.Logging; @@ -50,14 +51,25 @@ public interface IExportExecuteContext /// - /// The maximum allowed file name length + /// Identifier of current data stream. Can be null. /// - int MaxFileNameLength { get; } + string DataStreamId { get; set; } /// - /// The path of the export content folder + /// Stream used to write data to /// - string Folder { get; } + Stream DataStream { get; } + + /// + /// List with extra data streams required by provider + /// + List ExtraDataStreams { get; set; } + + + /// + /// The maximum allowed file name length + /// + int MaxFileNameLength { get; } /// /// The name of the current export file @@ -65,9 +77,9 @@ public interface IExportExecuteContext string FileName { get; } /// - /// The path of the current export file + /// The path of the export content folder /// - string FilePath { get; } + string Folder { get; } /// @@ -114,6 +126,25 @@ public interface IExportExecuteContext } + public class ExportExtraStreams + { + /// + /// Your Id to identify this stream within a list of streams + /// + public string Id { get; set; } + + /// + /// Stream used to write data to + /// + public Stream DataStream { get; internal set; } + + /// + /// The name of the file to be created + /// + public string FileName { get; set; } + } + + public class ExportExecuteContext : IExportExecuteContext { private DataExportResult _result; @@ -125,7 +156,7 @@ internal ExportExecuteContext(DataExportResult result, CancellationToken cancell _result = result; _cancellation = cancellation; Folder = folder; - + ExtraDataStreams = new List(); CustomProperties = new Dictionary(); } @@ -159,12 +190,13 @@ public bool IsMaxFailures get { return RecordsFailed > 11; } } - public int MaxFileNameLength { get; internal set; } + public string DataStreamId { get; set; } + public Stream DataStream { get; internal set; } + public List ExtraDataStreams { get; set; } - public string Folder { get; private set; } + public int MaxFileNameLength { get; internal set; } public string FileName { get; internal set; } - public string FileExtension { get; internal set; } - public string FilePath { get; internal set; } + public string Folder { get; private set; } public bool HasPublicDeployment { get; internal set; } public string PublicFolderPath { get; internal set; } diff --git a/src/Libraries/SmartStore.Services/DataExchange/ExportTask/ExportProfileTask.cs b/src/Libraries/SmartStore.Services/DataExchange/ExportTask/ExportProfileTask.cs index 1a52e264ea..8218acffb0 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/ExportTask/ExportProfileTask.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/ExportTask/ExportProfileTask.cs @@ -133,7 +133,7 @@ private void InitDependencies(TaskExecutionContext context) _genericAttributeService = context.Resolve>(); _subscriptionRepository = context.Resolve>>(); - T = NullLocalizer.Instance; + T = NullLocalizer.Instance; // TODO: resolve } public Localizer T { get; set; } @@ -316,6 +316,61 @@ private IExportDataSegmenterProvider CreateSegmenter(ExportProfileTaskContext ct return ctx.ExecuteContext.Segmenter as IExportDataSegmenterProvider; } + private bool CallProvider(ExportProfileTaskContext ctx, string streamId, string method, string path) + { + if (method != "Execute" && method != "OnExecuted") + throw new SmartException("Unknown export method {0}".FormatInvariant(method.NaIfEmpty())); + + try + { + ctx.ExecuteContext.DataStreamId = streamId; + + using (ctx.ExecuteContext.DataStream = new MemoryStream()) + { + if (method == "Execute") + { + ctx.Provider.Value.Execute(ctx.ExecuteContext); + } + else if (method == "OnExecuted") + { + ctx.Provider.Value.OnExecuted(ctx.ExecuteContext); + } + + if (ctx.IsFileBasedExport && path.HasValue()) + { + if (!ctx.ExecuteContext.DataStream.CanSeek) + ctx.Log.Warning("Data stream seems to be closed!"); + + ctx.ExecuteContext.DataStream.Seek(0, SeekOrigin.Begin); + + using (_rwLock.GetWriteLock()) + using (var fileStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.ReadWrite)) + { + ctx.Log.Information("Creating file " + path); + + ctx.ExecuteContext.DataStream.CopyTo(fileStream); + } + } + } + } + catch (Exception exc) + { + ctx.ExecuteContext.Abort = ExportAbortion.Hard; + ctx.Log.Error("The provider failed at the {0} method: {1}".FormatInvariant(method, exc.ToAllMessages()), exc); + ctx.Result.LastError = exc.ToString(); + } + finally + { + if (ctx.ExecuteContext.DataStream != null) + { + ctx.ExecuteContext.DataStream.Dispose(); + ctx.ExecuteContext.DataStream = null; + } + } + + return (ctx.ExecuteContext.Abort != ExportAbortion.Hard); + } + private void PrepareProductDescription(ExportProfileTaskContext ctx, dynamic expando, Product product) { try @@ -2465,12 +2520,12 @@ private void ExportCoreInner(ExportProfileTaskContext ctx, Store store) ctx.ExecuteContext.MaxFileNameLength = _dataExchangeSettings.Value.MaxFileNameLength; - ctx.ExecuteContext.FileExtension = (ctx.Provider.Value.FileExtension.HasValue() ? ctx.Provider.Value.FileExtension.ToLower().EnsureStartsWith(".") : ""); - ctx.ExecuteContext.HasPublicDeployment = ctx.Profile.Deployments.Any(x => x.IsPublic && x.DeploymentType == ExportDeploymentType.FileSystem); ctx.ExecuteContext.PublicFolderPath = (ctx.ExecuteContext.HasPublicDeployment ? Path.Combine(HttpRuntime.AppDomainAppPath, PublicFolder) : null); + var fileExtension = (ctx.Provider.Value.FileExtension.HasValue() ? ctx.Provider.Value.FileExtension.ToLower().EnsureStartsWith(".") : ""); + using (var segmenter = CreateSegmenter(ctx)) { @@ -2489,42 +2544,32 @@ private void ExportCoreInner(ExportProfileTaskContext ctx, Store store) segmenter.RecordPerSegmentCount = 0; ctx.ExecuteContext.RecordsSucceeded = 0; - try + string path = null; + + if (ctx.IsFileBasedExport) { - if (ctx.IsFileBasedExport) - { - var resolvedPattern = ctx.Profile.ResolveFileNamePattern(ctx.Store, ++fileIndex, ctx.ExecuteContext.MaxFileNameLength); + var resolvedPattern = ctx.Profile.ResolveFileNamePattern(ctx.Store, ++fileIndex, ctx.ExecuteContext.MaxFileNameLength); - ctx.ExecuteContext.FileName = resolvedPattern + ctx.ExecuteContext.FileExtension; - ctx.ExecuteContext.FilePath = Path.Combine(ctx.ExecuteContext.Folder, ctx.ExecuteContext.FileName); + ctx.ExecuteContext.FileName = resolvedPattern + fileExtension; + path = Path.Combine(ctx.ExecuteContext.Folder, ctx.ExecuteContext.FileName); - if (ctx.ExecuteContext.HasPublicDeployment) - ctx.ExecuteContext.PublicFileUrl = ctx.Store.Url.EnsureEndsWith("/") + PublicFolder.EnsureEndsWith("/") + ctx.ExecuteContext.FileName; + if (ctx.ExecuteContext.HasPublicDeployment) + ctx.ExecuteContext.PublicFileUrl = ctx.Store.Url.EnsureEndsWith("/") + PublicFolder.EnsureEndsWith("/") + ctx.ExecuteContext.FileName; + } - ctx.Provider.Value.Execute(ctx.ExecuteContext); + if (CallProvider(ctx, null, "Execute", path)) + { + ctx.Log.Information("Provider reports {0} successful exported record(s)".FormatInvariant(ctx.ExecuteContext.RecordsSucceeded)); - // create info for deployment list in profile edit - if (File.Exists(ctx.ExecuteContext.FilePath)) - { - ctx.Result.Files.Add(new DataExportResult.ExportFileInfo - { - StoreId = ctx.Store.Id, - FileName = ctx.ExecuteContext.FileName - }); - } - } - else + // create info for deployment list in profile edit + if (ctx.IsFileBasedExport) { - ctx.Provider.Value.Execute(ctx.ExecuteContext); + ctx.Result.Files.Add(new DataExportResult.ExportFileInfo + { + StoreId = ctx.Store.Id, + FileName = ctx.ExecuteContext.FileName + }); } - - ctx.Log.Information("Provider reports {0} successful exported record(s)".FormatInvariant(ctx.ExecuteContext.RecordsSucceeded)); - } - catch (Exception exc) - { - ctx.ExecuteContext.Abort = ExportAbortion.Hard; - ctx.Log.Error("The provider failed to execute the export: " + exc.ToAllMessages(), exc); - ctx.Result.LastError = exc.ToString(); } if (ctx.ExecuteContext.IsMaxFailures) @@ -2536,7 +2581,17 @@ private void ExportCoreInner(ExportProfileTaskContext ctx, Store store) if (ctx.ExecuteContext.Abort != ExportAbortion.Hard) { - ctx.Provider.Value.OnExecuted(ctx.ExecuteContext); + if (ctx.ExecuteContext.ExtraDataStreams.Count == 0) + ctx.ExecuteContext.ExtraDataStreams.Add(new ExportExtraStreams()); + + ctx.ExecuteContext.ExtraDataStreams.ForEach(x => + { + var path = (x.FileName.HasValue() ? Path.Combine(ctx.ExecuteContext.Folder, x.FileName) : null); + + CallProvider(ctx, x.Id, "OnExecuted", path); + }); + + ctx.ExecuteContext.ExtraDataStreams.Clear(); } } } @@ -2550,7 +2605,6 @@ private void ExportCoreOuter(ExportProfileTaskContext ctx) FileSystemHelper.ClearDirectory(ctx.FolderContent, false); FileSystemHelper.Delete(ctx.ZipPath); - using (_rwLock.GetWriteLock()) using (var logger = new TraceLogger(ctx.LogPath)) { try diff --git a/src/Libraries/SmartStore.Services/DataExchange/ExportXmlHelper.cs b/src/Libraries/SmartStore.Services/DataExchange/ExportXmlHelper.cs index e5837578d6..d58c724eac 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/ExportXmlHelper.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/ExportXmlHelper.cs @@ -24,7 +24,18 @@ public ExportXmlHelper(Stream stream, XmlWriterSettings settings = null, Culture { if (settings == null) { - settings = new XmlWriterSettings + settings = DefaultSettings; + } + + _writer = XmlWriter.Create(stream, settings); + _culture = (culture == null ? CultureInfo.InvariantCulture : culture); + } + + public static XmlWriterSettings DefaultSettings + { + get + { + return new XmlWriterSettings { Encoding = Encoding.UTF8, CheckCharacters = false, @@ -32,9 +43,6 @@ public ExportXmlHelper(Stream stream, XmlWriterSettings settings = null, Culture IndentChars = "\t" }; } - - _writer = XmlWriter.Create(stream, settings); - _culture = (culture == null ? CultureInfo.InvariantCulture : culture); } public XmlWriter Writer diff --git a/src/Libraries/SmartStore.Services/DataExchange/Providers/CategoryXmlExportProvider.cs b/src/Libraries/SmartStore.Services/DataExchange/Providers/CategoryXmlExportProvider.cs index 2b74231730..1aecac8667 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Providers/CategoryXmlExportProvider.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Providers/CategoryXmlExportProvider.cs @@ -1,8 +1,6 @@ using System; -using System.IO; using SmartStore.Core; using SmartStore.Core.Domain.DataExchange; -using SmartStore.Core.Logging; using SmartStore.Core.Plugins; namespace SmartStore.Services.DataExchange.Providers @@ -32,12 +30,7 @@ public override string FileExtension public override void Execute(IExportExecuteContext context) { - var path = context.FilePath; - - context.Log.Information("Creating file " + path); - - using (var stream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.ReadWrite)) - using (var helper = new ExportXmlHelper(stream)) + using (var helper = new ExportXmlHelper(context.DataStream)) { helper.Writer.WriteStartDocument(); helper.Writer.WriteStartElement("Categories"); diff --git a/src/Libraries/SmartStore.Services/DataExchange/Providers/CustomerXlsxExportProvider.cs b/src/Libraries/SmartStore.Services/DataExchange/Providers/CustomerXlsxExportProvider.cs index 4ab09bd5c5..72bda50969 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Providers/CustomerXlsxExportProvider.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Providers/CustomerXlsxExportProvider.cs @@ -1,12 +1,10 @@ using System; using System.Drawing; using System.Globalization; -using System.IO; using OfficeOpenXml; using OfficeOpenXml.Style; using SmartStore.Core.Domain.Customers; using SmartStore.Core.Domain.DataExchange; -using SmartStore.Core.Logging; using SmartStore.Core.Plugins; using SmartStore.Services.Customers; @@ -110,12 +108,8 @@ public override string FileExtension public override void Execute(IExportExecuteContext context) { var invariantCulture = CultureInfo.InvariantCulture; - var path = context.FilePath; - context.Log.Information("Creating file " + path); - - using (var stream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.ReadWrite)) - using (var xlPackage = new ExcelPackage(stream)) + using (var xlPackage = new ExcelPackage(context.DataStream)) { // uncomment this line if you want the XML written out to the outputDir //xlPackage.DebugMode = true; diff --git a/src/Libraries/SmartStore.Services/DataExchange/Providers/CustomerXmlExportProvider.cs b/src/Libraries/SmartStore.Services/DataExchange/Providers/CustomerXmlExportProvider.cs index 4103b412a5..4963380787 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Providers/CustomerXmlExportProvider.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Providers/CustomerXmlExportProvider.cs @@ -1,8 +1,6 @@ using System; -using System.IO; using SmartStore.Core; using SmartStore.Core.Domain.DataExchange; -using SmartStore.Core.Logging; using SmartStore.Core.Plugins; namespace SmartStore.Services.DataExchange.Providers @@ -32,12 +30,7 @@ public override string FileExtension public override void Execute(IExportExecuteContext context) { - var path = context.FilePath; - - context.Log.Information("Creating file " + path); - - using (var stream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.ReadWrite)) - using (var helper = new ExportXmlHelper(stream)) + using (var helper = new ExportXmlHelper(context.DataStream)) { helper.Writer.WriteStartDocument(); helper.Writer.WriteStartElement("Customers"); diff --git a/src/Libraries/SmartStore.Services/DataExchange/Providers/ManufacturerXmlExportProvider.cs b/src/Libraries/SmartStore.Services/DataExchange/Providers/ManufacturerXmlExportProvider.cs index 3c5d6afa53..af672aeed8 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Providers/ManufacturerXmlExportProvider.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Providers/ManufacturerXmlExportProvider.cs @@ -1,8 +1,6 @@ using System; -using System.IO; using SmartStore.Core; using SmartStore.Core.Domain.DataExchange; -using SmartStore.Core.Logging; using SmartStore.Core.Plugins; namespace SmartStore.Services.DataExchange.Providers @@ -32,12 +30,7 @@ public override string FileExtension public override void Execute(IExportExecuteContext context) { - var path = context.FilePath; - - context.Log.Information("Creating file " + path); - - using (var stream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.ReadWrite)) - using (var helper = new ExportXmlHelper(stream)) + using (var helper = new ExportXmlHelper(context.DataStream)) { helper.Writer.WriteStartDocument(); helper.Writer.WriteStartElement("Manufacturers"); diff --git a/src/Libraries/SmartStore.Services/DataExchange/Providers/OrderXlsxExportProvider.cs b/src/Libraries/SmartStore.Services/DataExchange/Providers/OrderXlsxExportProvider.cs index ae6ce4271d..0520409914 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Providers/OrderXlsxExportProvider.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Providers/OrderXlsxExportProvider.cs @@ -1,10 +1,8 @@ using System; using System.Drawing; -using System.IO; using OfficeOpenXml; using OfficeOpenXml.Style; using SmartStore.Core.Domain.DataExchange; -using SmartStore.Core.Logging; using SmartStore.Core.Plugins; namespace SmartStore.Services.DataExchange.Providers @@ -108,12 +106,7 @@ public override string FileExtension public override void Execute(IExportExecuteContext context) { - var path = context.FilePath; - - context.Log.Information("Creating file " + path); - - using (var stream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.ReadWrite)) - using (var xlPackage = new ExcelPackage(stream)) + using (var xlPackage = new ExcelPackage(context.DataStream)) { // uncomment this line if you want the XML written out to the outputDir //xlPackage.DebugMode = true; diff --git a/src/Libraries/SmartStore.Services/DataExchange/Providers/OrderXmlExportProvider.cs b/src/Libraries/SmartStore.Services/DataExchange/Providers/OrderXmlExportProvider.cs index 470155603a..366dcd15d0 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Providers/OrderXmlExportProvider.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Providers/OrderXmlExportProvider.cs @@ -1,9 +1,7 @@ using System; using System.Globalization; -using System.IO; using SmartStore.Core; using SmartStore.Core.Domain.DataExchange; -using SmartStore.Core.Logging; using SmartStore.Core.Plugins; namespace SmartStore.Services.DataExchange.Providers @@ -33,13 +31,9 @@ public override string FileExtension public override void Execute(IExportExecuteContext context) { - var path = context.FilePath; var invariantCulture = CultureInfo.InvariantCulture; - context.Log.Information("Creating file " + path); - - using (var stream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.ReadWrite)) - using (var helper = new ExportXmlHelper(stream)) + using (var helper = new ExportXmlHelper(context.DataStream)) { helper.Writer.WriteStartDocument(); helper.Writer.WriteStartElement("Orders"); diff --git a/src/Libraries/SmartStore.Services/DataExchange/Providers/ProductXlsxExportProvider.cs b/src/Libraries/SmartStore.Services/DataExchange/Providers/ProductXlsxExportProvider.cs index 3da13558c0..d2e877b7f8 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Providers/ProductXlsxExportProvider.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Providers/ProductXlsxExportProvider.cs @@ -1,14 +1,12 @@ using System; using System.Collections.Generic; using System.Drawing; -using System.IO; using System.Linq; using OfficeOpenXml; using OfficeOpenXml.Style; using SmartStore.Core.Domain.Catalog; using SmartStore.Core.Domain.DataExchange; using SmartStore.Core.Domain.Localization; -using SmartStore.Core.Logging; using SmartStore.Core.Plugins; using SmartStore.Services.Catalog; using SmartStore.Services.Localization; @@ -177,12 +175,7 @@ public override string FileExtension public override void Execute(IExportExecuteContext context) { - var path = context.FilePath; - - context.Log.Information("Creating file " + path); - - using (var stream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.ReadWrite)) - using (var xlPackage = new ExcelPackage(stream)) + using (var xlPackage = new ExcelPackage(context.DataStream)) { // uncomment this line if you want the XML written out to the outputDir //xlPackage.DebugMode = true; diff --git a/src/Libraries/SmartStore.Services/DataExchange/Providers/ProductXmlExportProvider.cs b/src/Libraries/SmartStore.Services/DataExchange/Providers/ProductXmlExportProvider.cs index a3480bdb3a..63d5dc4122 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Providers/ProductXmlExportProvider.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Providers/ProductXmlExportProvider.cs @@ -1,8 +1,6 @@ using System; -using System.IO; using SmartStore.Core; using SmartStore.Core.Domain.DataExchange; -using SmartStore.Core.Logging; using SmartStore.Core.Plugins; namespace SmartStore.Services.DataExchange.Providers @@ -32,12 +30,7 @@ public override string FileExtension public override void Execute(IExportExecuteContext context) { - var path = context.FilePath; - - context.Log.Information("Creating file " + path); - - using (var stream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.ReadWrite)) - using (var helper = new ExportXmlHelper(stream)) + using (var helper = new ExportXmlHelper(context.DataStream)) { helper.Writer.WriteStartDocument(); helper.Writer.WriteStartElement("Products"); diff --git a/src/Libraries/SmartStore.Services/DataExchange/Providers/SubscriberCsvExportProvider.cs b/src/Libraries/SmartStore.Services/DataExchange/Providers/SubscriberCsvExportProvider.cs index 2a7e299b51..be904fa6c7 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Providers/SubscriberCsvExportProvider.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Providers/SubscriberCsvExportProvider.cs @@ -2,7 +2,6 @@ using System.IO; using System.Text; using SmartStore.Core.Domain.DataExchange; -using SmartStore.Core.Logging; using SmartStore.Core.Plugins; namespace SmartStore.Services.DataExchange.Providers @@ -32,12 +31,7 @@ public override string FileExtension public override void Execute(IExportExecuteContext context) { - var path = context.FilePath; - - context.Log.Information("Creating file " + path); - - using (var stream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.ReadWrite)) - using (var writer = new StreamWriter(stream, Encoding.UTF8)) + using (var writer = new StreamWriter(context.DataStream, Encoding.UTF8, 1024, true)) { while (context.Abort == ExportAbortion.None && context.Segmenter.ReadNextSegment()) { diff --git a/src/Plugins/SmartStore.GoogleMerchantCenter/Providers/GmcXmlExportProvider.cs b/src/Plugins/SmartStore.GoogleMerchantCenter/Providers/GmcXmlExportProvider.cs index b1a68d4591..a58b4b98b8 100644 --- a/src/Plugins/SmartStore.GoogleMerchantCenter/Providers/GmcXmlExportProvider.cs +++ b/src/Plugins/SmartStore.GoogleMerchantCenter/Providers/GmcXmlExportProvider.cs @@ -1,7 +1,5 @@ using System; -using System.IO; using System.Linq; -using System.Text; using System.Xml; using SmartStore.Core.Domain.Catalog; using SmartStore.Core.Domain.DataExchange; @@ -157,13 +155,6 @@ public override string FileExtension public override void Execute(IExportExecuteContext context) { - var settings = new XmlWriterSettings - { - Encoding = Encoding.UTF8, - CheckCharacters = false - }; - - var path = context.FilePath; dynamic currency = context.Currency; string measureWeightSystemKey = ""; @@ -174,10 +165,7 @@ public override void Execute(IExportExecuteContext context) var config = (context.ConfigurationData as ProfileConfigurationModel) ?? new ProfileConfigurationModel(); - context.Log.Information("Creating file " + path); - - using (var stream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.ReadWrite)) - using (var writer = XmlWriter.Create(stream, settings)) + using (var writer = XmlWriter.Create(context.DataStream, ExportXmlHelper.DefaultSettings)) { writer.WriteStartDocument(); writer.WriteStartElement("rss"); From 738052a5be9af329f02181d7d2d9fdbd3839ce76 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Sun, 8 Nov 2015 19:47:39 +0100 Subject: [PATCH 004/626] ExportFeature becomes an enum of flags --- .../Domain/DataExchange/ExportEnums.cs | 32 +++++++++++-------- .../Plugins/Providers/ProviderMetadata.cs | 4 +-- .../DataExchange/ExportExtensions.cs | 16 ---------- .../DataExchange/ExportFeaturesAttribute.cs | 7 +--- .../DataExchange/ExportProfileService.cs | 4 +-- .../ExportTask/ExportProfileTask.cs | 18 +++++------ .../ExportTask/ExportProfileTaskContext.cs | 9 ++---- .../Providers/GmcXmlExportProvider.cs | 18 +++++------ .../DependencyRegistrar.cs | 8 ++--- .../Controllers/ExportController.cs | 2 +- .../Models/DataExchange/ExportProfileModel.cs | 2 +- .../Views/Export/_Tab.Projection.cshtml | 14 ++++---- 12 files changed, 56 insertions(+), 78 deletions(-) diff --git a/src/Libraries/SmartStore.Core/Domain/DataExchange/ExportEnums.cs b/src/Libraries/SmartStore.Core/Domain/DataExchange/ExportEnums.cs index b7f041fed5..90cb107353 100644 --- a/src/Libraries/SmartStore.Core/Domain/DataExchange/ExportEnums.cs +++ b/src/Libraries/SmartStore.Core/Domain/DataExchange/ExportEnums.cs @@ -1,4 +1,5 @@  +using System; namespace SmartStore.Core.Domain.DataExchange { /// @@ -59,64 +60,67 @@ public enum ExportAttributeValueMerging } /// - /// Controls data processing and projection items supported by export provider + /// Controls data processing and projection items supported by an export provider /// - public enum ExportFeatures + [Flags] + public enum ExportFeature { + None = 0, + /// /// Whether to automatically create a file based public deployment when an export profile is created /// - CreatesInitialPublicDeployment = 0, + CreatesInitialPublicDeployment = 1, /// /// Whether to offer option to include\exclude grouped products /// - CanOmitGroupedProducts, + CanOmitGroupedProducts = 1 << 2, /// /// Whether to offer option to export attribute combinations as products /// - CanProjectAttributeCombinations, + CanProjectAttributeCombinations = 1 << 3, /// /// Whether to offer further options to manipulate the product description /// - CanProjectDescription, + CanProjectDescription = 1 << 4, /// /// Whether to offer option to enter a brand fallback /// - OffersBrandFallback, + OffersBrandFallback = 1 << 5, /// /// Whether to offer option to set a picture size and to get the URL of the main image /// - CanIncludeMainPicture, + CanIncludeMainPicture = 1 << 6, /// /// Whether to use SKU as manufacturer part number if MPN is empty /// - UsesSkuAsMpnFallback, - + UsesSkuAsMpnFallback = 1 << 7, + /// /// Whether to offer option to enter a shipping time fallback /// - OffersShippingTimeFallback, + OffersShippingTimeFallback = 1 << 8, /// /// Whether to offer option to enter a shipping costs fallback and a free shipping threshold /// - OffersShippingCostsFallback, + OffersShippingCostsFallback = 1 << 9, /// /// Whether to get the calculated old product price /// - UsesOldPrice, + UsesOldPrice = 1 << 10, /// /// Whether to get the calculated special and regular price (ignoring special offers) /// - UsesSpecialPrice + UsesSpecialPrice = 1 << 11 } /// diff --git a/src/Libraries/SmartStore.Core/Plugins/Providers/ProviderMetadata.cs b/src/Libraries/SmartStore.Core/Plugins/Providers/ProviderMetadata.cs index 31d98942d4..05ef601ecc 100644 --- a/src/Libraries/SmartStore.Core/Plugins/Providers/ProviderMetadata.cs +++ b/src/Libraries/SmartStore.Core/Plugins/Providers/ProviderMetadata.cs @@ -74,9 +74,9 @@ public class ProviderMetadata public bool IsHidden { get; set; } /// - /// Gets or sets an array of values that reflects what export data processing is supported by a provider + /// Gets or sets flags that reflects what features of export data processing is supported by a provider /// - public ExportFeatures[] ExportSupport { get; set; } + public ExportFeature ExportFeature { get; set; } /// /// Gets or sets an array of widget system names, which depend on the current provider diff --git a/src/Libraries/SmartStore.Services/DataExchange/ExportExtensions.cs b/src/Libraries/SmartStore.Services/DataExchange/ExportExtensions.cs index ae5b8ff6ce..a7a8e5c5b9 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/ExportExtensions.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/ExportExtensions.cs @@ -1,10 +1,8 @@ using System; using System.IO; -using System.Linq; using System.Web; using System.Web.Caching; using SmartStore.Core.Domain; -using SmartStore.Core.Domain.DataExchange; using SmartStore.Core.Domain.Stores; using SmartStore.Core.Plugins; using SmartStore.Services.Localization; @@ -24,20 +22,6 @@ public static bool IsValid(this Provider provider) return provider != null; } - /// - /// Returns a value indicating whether the export provider supports a projection type - /// - /// Export provider - /// The feature to check - /// true provider supports type, false provider does not support type. - public static bool Supports(this Provider provider, ExportFeatures feature) - { - if (provider != null) - return provider.Metadata.ExportSupport.Contains(feature); - - return false; - } - /// /// Gets the localized friendly name or the system name as fallback /// diff --git a/src/Libraries/SmartStore.Services/DataExchange/ExportFeaturesAttribute.cs b/src/Libraries/SmartStore.Services/DataExchange/ExportFeaturesAttribute.cs index d29f5641d3..7f803715f4 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/ExportFeaturesAttribute.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/ExportFeaturesAttribute.cs @@ -10,11 +10,6 @@ namespace SmartStore.Services.DataExchange [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)] public sealed class ExportFeaturesAttribute : Attribute { - public ExportFeaturesAttribute(params ExportFeatures[] features) - { - Features = features; - } - - public ExportFeatures[] Features { get; set; } + public ExportFeature Features { get; set; } } } diff --git a/src/Libraries/SmartStore.Services/DataExchange/ExportProfileService.cs b/src/Libraries/SmartStore.Services/DataExchange/ExportProfileService.cs index dac3287770..95302de285 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/ExportProfileService.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/ExportProfileService.cs @@ -116,7 +116,7 @@ public virtual ExportProfile InsertExportProfile(Provider provi RemoveCriticalCharacters = true, CriticalCharacters = "¼,½,¾", PriceType = PriceDisplayType.PreSelectedPrice, - NoGroupedProducts = (provider.Supports(ExportFeatures.CanOmitGroupedProducts) ? true : false) + NoGroupedProducts = (provider.Metadata.ExportFeature.HasFlag(ExportFeature.CanOmitGroupedProducts) ? true : false) }; var filter = new ExportFilter @@ -150,7 +150,7 @@ public virtual ExportProfile InsertExportProfile(Provider provi { if (cloneProfile == null) { - if (provider.Supports(ExportFeatures.CreatesInitialPublicDeployment)) + if (provider.Metadata.ExportFeature.HasFlag(ExportFeature.CreatesInitialPublicDeployment)) { profile.Deployments.Add(new ExportDeployment { diff --git a/src/Libraries/SmartStore.Services/DataExchange/ExportTask/ExportProfileTask.cs b/src/Libraries/SmartStore.Services/DataExchange/ExportTask/ExportProfileTask.cs index 8218acffb0..b796715059 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/ExportTask/ExportProfileTask.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/ExportTask/ExportProfileTask.cs @@ -1539,7 +1539,7 @@ private List ConvertToExpando(ExportProfileTaskContext ctx, Product pro var productTemplate = ctx.ProductTemplates.FirstOrDefault(x => x.Key == product.ProductTemplateId); var pictureSize = _mediaSettings.Value.ProductDetailsPictureSize; - if (ctx.SupportedFeatures[ExportFeatures.CanIncludeMainPicture] && ctx.Projection.PictureSize > 0) + if (ctx.Supports(ExportFeature.CanIncludeMainPicture) && ctx.Projection.PictureSize > 0) pictureSize = ctx.Projection.PictureSize; var perfLoadId = (ctx.IsPreview ? 0 : product.Id); // perf preview (it's a compromise) @@ -1745,12 +1745,12 @@ private List ConvertToExpando(ExportProfileTaskContext ctx, Product pro #region more attribute controlled data - if (ctx.Supports(ExportFeatures.CanProjectDescription)) + if (ctx.Supports(ExportFeature.CanProjectDescription)) { PrepareProductDescription(ctx, expando, product); } - if (ctx.Supports(ExportFeatures.OffersBrandFallback)) + if (ctx.Supports(ExportFeature.OffersBrandFallback)) { string brand = null; var productManus = ctx.ProductExportContext.ProductManufacturers.Load(perfLoadId); @@ -1764,7 +1764,7 @@ private List ConvertToExpando(ExportProfileTaskContext ctx, Product pro expando._Brand = brand; } - if (ctx.Supports(ExportFeatures.CanIncludeMainPicture)) + if (ctx.Supports(ExportFeature.CanIncludeMainPicture)) { if (productPictures != null && productPictures.Any()) expando._MainPictureUrl = _pictureService.Value.GetPictureUrl(productPictures.First().Picture, ctx.Projection.PictureSize, storeLocation: ctx.Store.Url); @@ -1806,18 +1806,18 @@ private List ConvertToExpando(ExportProfileTaskContext ctx, Product pro // navigation properties GetDeliveryTimeAndQuantityUnit(ctx, exp, product.DeliveryTimeId, product.QuantityUnitId); - if (ctx.Supports(ExportFeatures.UsesSkuAsMpnFallback) && product.ManufacturerPartNumber.IsEmpty()) + if (ctx.Supports(ExportFeature.UsesSkuAsMpnFallback) && product.ManufacturerPartNumber.IsEmpty()) { exp.ManufacturerPartNumber = product.Sku; } - if (ctx.Supports(ExportFeatures.OffersShippingTimeFallback)) + if (ctx.Supports(ExportFeature.OffersShippingTimeFallback)) { dynamic deliveryTime = exp.DeliveryTime; exp._ShippingTime = (deliveryTime == null ? ctx.Projection.ShippingTime : deliveryTime.Name); } - if (ctx.Supports(ExportFeatures.OffersShippingCostsFallback)) + if (ctx.Supports(ExportFeature.OffersShippingCostsFallback)) { exp._FreeShippingThreshold = ctx.Projection.FreeShippingThreshold; @@ -1827,7 +1827,7 @@ private List ConvertToExpando(ExportProfileTaskContext ctx, Product pro exp._ShippingCosts = ctx.Projection.ShippingCosts; } - if (ctx.Supports(ExportFeatures.UsesOldPrice)) + if (ctx.Supports(ExportFeature.UsesOldPrice)) { if (product.OldPrice != decimal.Zero && product.OldPrice != (decimal)exp.Price && !(product.ProductType == ProductType.BundledProduct && product.BundlePerItemPricing)) { @@ -1847,7 +1847,7 @@ private List ConvertToExpando(ExportProfileTaskContext ctx, Product pro } } - if (ctx.Supports(ExportFeatures.UsesSpecialPrice)) + if (ctx.Supports(ExportFeature.UsesSpecialPrice)) { exp._SpecialPrice = null; exp._RegularPrice = null; // price if a special price would not exist diff --git a/src/Libraries/SmartStore.Services/DataExchange/ExportTask/ExportProfileTaskContext.cs b/src/Libraries/SmartStore.Services/DataExchange/ExportTask/ExportProfileTaskContext.cs index 8c1286b5d6..ae14972e42 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/ExportTask/ExportProfileTaskContext.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/ExportTask/ExportProfileTaskContext.cs @@ -41,10 +41,6 @@ public ExportProfileTaskContext( EntityIdsSelected = selectedIds.SplitSafe(",").Select(x => x.ToInt()).ToList(); PreviewData = previewData; - SupportedFeatures = Enum.GetValues(typeof(ExportFeatures)) - .Cast() - .ToDictionary(x => x, x => Provider.Supports(x)); - FolderContent = FileSystemHelper.TempDir(@"Profile\Export\{0}\Content".FormatInvariant(profile.FolderName)); FolderRoot = System.IO.Directory.GetParent(FolderContent).FullName; @@ -84,10 +80,9 @@ public bool IsPreview public ExportProfile Profile { get; private set; } public Provider Provider { get; private set; } - public Dictionary SupportedFeatures { get; private set; } - public bool Supports(ExportFeatures feature) + public bool Supports(ExportFeature feature) { - return (!IsPreview && SupportedFeatures[feature]); + return (!IsPreview && Provider.Metadata.ExportFeature.HasFlag(feature)); } public ExportFilter Filter { get; private set; } diff --git a/src/Plugins/SmartStore.GoogleMerchantCenter/Providers/GmcXmlExportProvider.cs b/src/Plugins/SmartStore.GoogleMerchantCenter/Providers/GmcXmlExportProvider.cs index a58b4b98b8..852f8eb430 100644 --- a/src/Plugins/SmartStore.GoogleMerchantCenter/Providers/GmcXmlExportProvider.cs +++ b/src/Plugins/SmartStore.GoogleMerchantCenter/Providers/GmcXmlExportProvider.cs @@ -17,15 +17,15 @@ namespace SmartStore.GoogleMerchantCenter.Providers [SystemName("Feeds.GoogleMerchantCenterProductXml")] [FriendlyName("Google Merchant Center XML product feed")] [DisplayOrder(1)] - [ExportFeatures( - ExportFeatures.CreatesInitialPublicDeployment, - ExportFeatures.CanOmitGroupedProducts, - ExportFeatures.CanProjectAttributeCombinations, - ExportFeatures.CanProjectDescription, - ExportFeatures.UsesSkuAsMpnFallback, - ExportFeatures.OffersBrandFallback, - ExportFeatures.CanIncludeMainPicture, - ExportFeatures.UsesSpecialPrice)] + [ExportFeatures(Features = + ExportFeature.CreatesInitialPublicDeployment | + ExportFeature.CanOmitGroupedProducts | + ExportFeature.CanProjectAttributeCombinations | + ExportFeature.CanProjectDescription | + ExportFeature.UsesSkuAsMpnFallback | + ExportFeature.OffersBrandFallback | + ExportFeature.CanIncludeMainPicture | + ExportFeature.UsesSpecialPrice)] public class GmcXmlExportProvider : ExportProviderBase { private const string _googleNamespace = "http://base.google.com/ns/1.0"; diff --git a/src/Presentation/SmartStore.Web.Framework/DependencyRegistrar.cs b/src/Presentation/SmartStore.Web.Framework/DependencyRegistrar.cs index 1daa71bd03..2b11924761 100644 --- a/src/Presentation/SmartStore.Web.Framework/DependencyRegistrar.cs +++ b/src/Presentation/SmartStore.Web.Framework/DependencyRegistrar.cs @@ -768,7 +768,7 @@ protected override void Load(ContainerBuilder builder) var isConfigurable = typeof(IConfigurable).IsAssignableFrom(type); var isEditable = typeof(IUserEditable).IsAssignableFrom(type); var isHidden = GetIsHidden(type); - var exportSupport = GetExportFeatures(type); + var exportFeature = GetExportFeature(type); var registration = builder.RegisterType(type).Named(systemName).InstancePerRequest().PropertiesAutowired(PropertyWiringOptions.None); registration.WithMetadata(m => @@ -785,7 +785,7 @@ protected override void Load(ContainerBuilder builder) m.For(em => em.IsConfigurable, isConfigurable); m.For(em => em.IsEditable, isEditable); m.For(em => em.IsHidden, isHidden); - m.For(em => em.ExportSupport, exportSupport); + m.For(em => em.ExportFeature, exportFeature); }); // register specific provider type @@ -863,7 +863,7 @@ private bool GetIsHidden(Type type) return false; } - private ExportFeatures[] GetExportFeatures(Type type) + private ExportFeature GetExportFeature(Type type) { var attr = type.GetAttribute(false); @@ -872,7 +872,7 @@ private ExportFeatures[] GetExportFeatures(Type type) return attr.Features; } - return new ExportFeatures[0]; + return ExportFeature.None; } private Tuple GetFriendlyName(Type type, PluginDescriptor descriptor) diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs index 29c4c040b9..8690b4507c 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs @@ -279,7 +279,7 @@ private void PrepareProfileModelForEdit(ExportProfileModel model, ExportProfile if (provider != null) { - model.Provider.Supporting = provider.Metadata.ExportSupport; + model.Provider.Feature = provider.Metadata.ExportFeature; if (model.Provider.EntityType == ExportEntityType.Product) { diff --git a/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ExportProfileModel.cs b/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ExportProfileModel.cs index 3ebf4350d9..ee44a44113 100644 --- a/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ExportProfileModel.cs +++ b/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ExportProfileModel.cs @@ -94,7 +94,7 @@ public class ProviderModel public Type ConfigDataType { get; set; } public object ConfigData { get; set; } - public ExportFeatures[] Supporting { get; set; } + public ExportFeature Feature { get; set; } [SmartResourceDisplayName("Common.Image")] public string ThumbnailUrl { get; set; } diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Export/_Tab.Projection.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Export/_Tab.Projection.cshtml index 4815fba951..3d02c0a230 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Export/_Tab.Projection.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Export/_Tab.Projection.cshtml @@ -42,7 +42,7 @@ @if (Model.Provider.EntityType == ExportEntityType.Product) { - if (Model.Provider.Supporting.Contains(ExportFeatures.CanProjectAttributeCombinations)) + if (Model.Provider.Feature.HasFlag(ExportFeature.CanProjectAttributeCombinations)) { @@ -71,7 +71,7 @@ } - if (Model.Provider.Supporting.Contains(ExportFeatures.CanOmitGroupedProducts)) + if (Model.Provider.Feature.HasFlag(ExportFeature.CanOmitGroupedProducts)) { @@ -110,7 +110,7 @@ - if (Model.Provider.Supporting.Contains(ExportFeatures.OffersShippingTimeFallback)) + if (Model.Provider.Feature.HasFlag(ExportFeature.OffersShippingTimeFallback)) { @@ -123,7 +123,7 @@ } - if (Model.Provider.Supporting.Contains(ExportFeatures.OffersShippingCostsFallback)) + if (Model.Provider.Feature.HasFlag(ExportFeature.OffersShippingCostsFallback)) { @@ -145,7 +145,7 @@ } - if (Model.Provider.Supporting.Contains(ExportFeatures.CanIncludeMainPicture)) + if (Model.Provider.Feature.HasFlag(ExportFeature.CanIncludeMainPicture)) { @@ -158,7 +158,7 @@ } - if (Model.Provider.Supporting.Contains(ExportFeatures.OffersBrandFallback)) + if (Model.Provider.Feature.HasFlag(ExportFeature.OffersBrandFallback)) { @@ -171,7 +171,7 @@ } - if (Model.Provider.Supporting.Contains(ExportFeatures.CanProjectDescription)) + if (Model.Provider.Feature.HasFlag(ExportFeature.CanProjectDescription)) { From 6d1e4ad7a7e7f9e1c6cb5723b7c1d292c1e231ad Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Mon, 9 Nov 2015 11:01:35 +0100 Subject: [PATCH 005/626] Fixed issues due to incomplete renaming --- .../FeedGoogleMerchantCenter/Configure.cshtml | 2 +- .../ProfileConfiguration.cshtml | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/Plugins/SmartStore.GoogleMerchantCenter/Views/FeedGoogleMerchantCenter/Configure.cshtml b/src/Plugins/SmartStore.GoogleMerchantCenter/Views/FeedGoogleMerchantCenter/Configure.cshtml index 8d01b7baeb..6312648112 100644 --- a/src/Plugins/SmartStore.GoogleMerchantCenter/Views/FeedGoogleMerchantCenter/Configure.cshtml +++ b/src/Plugins/SmartStore.GoogleMerchantCenter/Views/FeedGoogleMerchantCenter/Configure.cshtml @@ -22,7 +22,7 @@ @Html.Raw(@T("Plugins.Feed.Froogle.AdminInstruction"))
- @Html.Action("InfoProfile", "Export", new { systemName = ProductExportXmlProvider.SystemName, returnUrl = Request.RawUrl, area = "admin" }) + @Html.Action("InfoProfile", "Export", new { systemName = GmcXmlExportProvider.SystemName, returnUrl = Request.RawUrl, area = "admin" })
diff --git a/src/Plugins/SmartStore.GoogleMerchantCenter/Views/FeedGoogleMerchantCenter/ProfileConfiguration.cshtml b/src/Plugins/SmartStore.GoogleMerchantCenter/Views/FeedGoogleMerchantCenter/ProfileConfiguration.cshtml index 57b1c7b693..edf7fecb7e 100644 --- a/src/Plugins/SmartStore.GoogleMerchantCenter/Views/FeedGoogleMerchantCenter/ProfileConfiguration.cshtml +++ b/src/Plugins/SmartStore.GoogleMerchantCenter/Views/FeedGoogleMerchantCenter/ProfileConfiguration.cshtml @@ -39,9 +39,10 @@ @Html.SmartLabelFor(m => m.Condition) - @Html.DropDownList("Condition", new List { + @Html.DropDownList("Condition", new List + { new SelectListItem { Text = T("Common.Auto"), Value = "" }, - new SelectListItem { Text = T("Common.Unspecified"), Value = ProductExportXmlProvider.Unspecified }, + new SelectListItem { Text = T("Common.Unspecified"), Value = GmcXmlExportProvider.Unspecified }, new SelectListItem { Text = T("Plugins.Feed.Froogle.ConditionNew"), Value = "new" }, new SelectListItem { Text = T("Plugins.Feed.Froogle.ConditionUsed"), Value = "used" }, new SelectListItem { Text = T("Plugins.Feed.Froogle.ConditionRefurbished"), Value = "refurbished" } @@ -54,9 +55,10 @@ @Html.SmartLabelFor(m => m.Availability) - @Html.DropDownList("Availability", new List { + @Html.DropDownList("Availability", new List + { new SelectListItem { Text = T("Common.Auto"), Value = "" }, - new SelectListItem { Text = T("Common.Unspecified"), Value = ProductExportXmlProvider.Unspecified }, + new SelectListItem { Text = T("Common.Unspecified"), Value = GmcXmlExportProvider.Unspecified }, new SelectListItem { Text = T("Plugins.Feed.Froogle.AvailabilityInStock"), Value = "in stock" }, new SelectListItem { Text = T("Plugins.Feed.Froogle.AvailabilityOutOfStock"), Value = "out of stock" }, new SelectListItem { Text = T("Plugins.Feed.Froogle.AvailabilityPreorder"), Value = "preorder" } @@ -71,7 +73,7 @@ @Html.DropDownList("Gender", new List { new SelectListItem { Text = T("Common.Auto"), Value = "" }, - new SelectListItem { Text = T("Common.Unspecified"), Value = ProductExportXmlProvider.Unspecified }, + new SelectListItem { Text = T("Common.Unspecified"), Value = GmcXmlExportProvider.Unspecified }, new SelectListItem { Text = T("Plugins.Feed.Froogle.GenderMale"), Value = "male" }, new SelectListItem { Text = T("Plugins.Feed.Froogle.GenderFemale"), Value = "female" }, new SelectListItem { Text = T("Plugins.Feed.Froogle.GenderUnisex"), Value = "unisex" } @@ -86,7 +88,7 @@ @Html.DropDownList("AgeGroup", new List { new SelectListItem { Text = T("Common.Auto"), Value = "" }, - new SelectListItem { Text = T("Common.Unspecified"), Value = ProductExportXmlProvider.Unspecified }, + new SelectListItem { Text = T("Common.Unspecified"), Value = GmcXmlExportProvider.Unspecified }, new SelectListItem { Text = T("Plugins.Feed.Froogle.AgeGroupAdult"), Value = "adult" }, new SelectListItem { Text = T("Plugins.Feed.Froogle.AgeGroupKids"), Value = "kids" } }) From d75613c885bf853b4e647b0e3f9ce8cf1aaad01d Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Mon, 9 Nov 2015 12:50:37 +0100 Subject: [PATCH 006/626] Improved pattern resolving of export file names --- .../201509021536425_ExportFramework1.cs | 4 +- .../201509150931528_ExportFramework2.cs | 5 ++ .../DataExchange/ExportExtensions.cs | 33 ++++++--- .../DataExchange/ExportProfileService.cs | 2 +- .../Controllers/ExportController.cs | 1 + .../Models/DataExchange/ExportProfileModel.cs | 1 + .../Views/Export/_Tab.Deployment.cshtml | 70 ++++++++++++++++++- 7 files changed, 103 insertions(+), 13 deletions(-) diff --git a/src/Libraries/SmartStore.Data/Migrations/201509021536425_ExportFramework1.cs b/src/Libraries/SmartStore.Data/Migrations/201509021536425_ExportFramework1.cs index d8e9b8ab9d..ed09b5e8d3 100644 --- a/src/Libraries/SmartStore.Data/Migrations/201509021536425_ExportFramework1.cs +++ b/src/Libraries/SmartStore.Data/Migrations/201509021536425_ExportFramework1.cs @@ -100,8 +100,8 @@ public void MigrateLocaleResources(LocaleResourcesBuilder builder) "Legt den Namen des Ordners fest, in den die Daten exportiert werden."); builder.AddOrUpdate("Admin.DataExchange.Export.FolderAndFileName.Validate", - "Please enter a valid folder and file name. Example for file names: %Misc.FileNumber%-%ExportProfile.Id%-gmc-%Store.Name%", - "Bitte einen gltigen Ordner- und Dateinamen eingeben. Beispiel fr Dateinamen: %Misc.FileNumber%-%ExportProfile.Id%-gmc-%Store.Name%"); + "Please enter a valid folder and file name. Example for file names: %File.Index%-%Profile.Id%-gmc-%Store.Name%", + "Bitte einen gltigen Ordner- und Dateinamen eingeben. Beispiel fr Dateinamen: %File.Index%-%Profile.Id%-gmc-%Store.Name%"); builder.AddOrUpdate("Admin.DataExchange.Export.Deployment.CreateZip", diff --git a/src/Libraries/SmartStore.Data/Migrations/201509150931528_ExportFramework2.cs b/src/Libraries/SmartStore.Data/Migrations/201509150931528_ExportFramework2.cs index 174f2d1f44..ccc5a52b37 100644 --- a/src/Libraries/SmartStore.Data/Migrations/201509150931528_ExportFramework2.cs +++ b/src/Libraries/SmartStore.Data/Migrations/201509150931528_ExportFramework2.cs @@ -41,6 +41,7 @@ public void MigrateLocaleResources(LocaleResourcesBuilder builder) builder.AddOrUpdate("Common.ShowAll", "Show all", "Alle anzeigen"); builder.AddOrUpdate("Admin.Common.Selected", "Selected", "Ausgewhlte"); builder.AddOrUpdate("Admin.Common.Entity", "Entity", "Entitt"); + builder.AddOrUpdate("Admin.Common.Placeholder", "Placeholder", "Platzhalter"); builder.AddOrUpdate("Admin.Common.FilesDeleted", @@ -108,6 +109,10 @@ public void MigrateLocaleResources(LocaleResourcesBuilder builder) "Pro Sprache darf nur ein aktiver SEO Name festgelegt werden."); + builder.AddOrUpdate("Admin.DataExchange.Export.FileNamePatternDescriptions", + "ID of export profil;Folder name of export profil;SEO name of export profil;Store ID;SEO name of store;One based file index;Random number;UTC timestamp", + "ID des Exportprofils;Ordername des Exportprofils;SEO Name des Exportprofils;Shop ID;SEO Name des Shops;Mit 1 beginnender Dateiindex;Zufallszahl;UTC Zeitstempel"); + builder.AddOrUpdate("Admin.DataExchange.Export.NotPreviewCompatible", "This option is not taken into account in the preview.", "Diese Option wird in der Vorschau nicht bercksichtigt."); diff --git a/src/Libraries/SmartStore.Services/DataExchange/ExportExtensions.cs b/src/Libraries/SmartStore.Services/DataExchange/ExportExtensions.cs index a7a8e5c5b9..8a0cdc959d 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/ExportExtensions.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/ExportExtensions.cs @@ -1,5 +1,7 @@ using System; +using System.Globalization; using System.IO; +using System.Text; using System.Web; using System.Web.Caching; using SmartStore.Core.Domain; @@ -64,18 +66,31 @@ public static string GetExportLogFilePath(this ExportProfile profile) ///
/// Export profile /// Store - /// File number + /// One based file index /// The maximum length of the file name /// Resolved file name pattern - public static string ResolveFileNamePattern(this ExportProfile profile, Store store, int fileNumber, int maxFileNameLength) + public static string ResolveFileNamePattern(this ExportProfile profile, Store store, int fileIndex, int maxFileNameLength) { - var result = profile.FileNamePattern - .Replace("%ExportProfile.Id%", profile.Id.ToString()) - .Replace("%ExportProfile.SeoName%", SeoHelper.GetSeName(profile.Name, true, false).Replace("/", "").Replace("-", "")) - .Replace("%ExportProfile.FolderName%", profile.FolderName) - .Replace("%Store.Id%", store.Id.ToString()) - .Replace("%Store.SeoName%", profile.PerStore ? SeoHelper.GetSeName(store.Name, true, false) : "allstores") - .Replace("%Misc.FileNumber%", fileNumber.ToString("D4")) + var sb = new StringBuilder(profile.FileNamePattern); + + sb.Replace("%Profile.Id%", profile.Id.ToString()); + sb.Replace("%Profile.FolderName%", profile.FolderName); + sb.Replace("%Store.Id%", store.Id.ToString()); + sb.Replace("%File.Index%", fileIndex.ToString("D4")); + + if (profile.FileNamePattern.Contains("%Profile.SeoName%")) + sb.Replace("%Profile.SeoName%", SeoHelper.GetSeName(profile.Name, true, false).Replace("/", "").Replace("-", "")); + + if (profile.FileNamePattern.Contains("%Store.SeoName%")) + sb.Replace("%Store.SeoName%", profile.PerStore ? SeoHelper.GetSeName(store.Name, true, false) : "allstores"); + + if (profile.FileNamePattern.Contains("%Random.Number%")) + sb.Replace("%Random.Number%", CommonHelper.GenerateRandomInteger().ToString()); + + if (profile.FileNamePattern.Contains("%Timestamp%")) + sb.Replace("%Timestamp%", DateTime.UtcNow.ToString("s", CultureInfo.InvariantCulture)); + + var result = sb.ToString() .ToValidFileName("") .Truncate(maxFileNameLength); diff --git a/src/Libraries/SmartStore.Services/DataExchange/ExportProfileService.cs b/src/Libraries/SmartStore.Services/DataExchange/ExportProfileService.cs index 95302de285..465b97a3c2 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/ExportProfileService.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/ExportProfileService.cs @@ -18,7 +18,7 @@ namespace SmartStore.Services.DataExchange { public partial class ExportProfileService : IExportProfileService { - private const string _defaultFileNamePattern = "%Store.Id%-%ExportProfile.Id%-%Misc.FileNumber%-%ExportProfile.SeoName%"; + private const string _defaultFileNamePattern = "%Store.Id%-%Profile.Id%-%File.Index%-%Profile.SeoName%"; private readonly IRepository _exportProfileRepository; private readonly IRepository _exportDeploymentRepository; diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs index 8690b4507c..0aa83791c2 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs @@ -113,6 +113,7 @@ private void PrepareProfileModel(ExportProfileModel model, ExportProfile profile model.IsTaskEnabled = profile.ScheduleTask.Enabled; model.LogFileExists = System.IO.File.Exists(profile.GetExportLogFilePath()); model.HasActiveProvider = (provider != null); + model.FileNamePatternDescriptions = T("Admin.DataExchange.Export.FileNamePatternDescriptions").Text.SplitSafe(";"); model.Provider = new ExportProfileModel.ProviderModel(); model.Provider.ThumbnailUrl = GetThumbnailUrl(provider); diff --git a/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ExportProfileModel.cs b/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ExportProfileModel.cs index ee44a44113..a863d55d3f 100644 --- a/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ExportProfileModel.cs +++ b/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ExportProfileModel.cs @@ -19,6 +19,7 @@ public partial class ExportProfileModel : EntityModelBase public string UnspecifiedString { get; set; } public bool LogFileExists { get; set; } public bool HasActiveProvider { get; set; } + public string[] FileNamePatternDescriptions { get; set; } [SmartResourceDisplayName("Admin.DataExchange.Export.Name")] public string Name { get; set; } diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Export/_Tab.Deployment.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Export/_Tab.Deployment.cshtml index 3e8d295898..17bfd46a84 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Export/_Tab.Deployment.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Export/_Tab.Deployment.cshtml @@ -23,6 +23,16 @@ @Html.TextBoxFor(x => x.FileNamePattern, new { @class = "input-large" }) @Html.ValidationMessageFor(x => x.FileNamePattern) + +
+
+ @T("Admin.Common.Show")... +
+ @FileNamePatternDescription() +
+
+ +
[DataContract] - public partial class Product : BaseEntity, ISoftDeletable, ILocalizedEntity, ISlugSupported, IAclSupported, IStoreMappingSupported, IMergedData - { + public partial class Product : BaseEntity, ISoftDeletable, ILocalizedEntity, ISlugSupported, IAclSupported, IStoreMappingSupported, IMergedData, ICloneable + { private ICollection _productCategories; private ICollection _productManufacturers; private ICollection _productPictures; @@ -1046,5 +1046,15 @@ public virtual ICollection ProductBundleItems get { return _productBundleItems ?? (_productBundleItems = new HashSet()); } protected set { _productBundleItems = value; } } - } + + public Product Clone() + { + return (Product)this.MemberwiseClone(); + } + + object ICloneable.Clone() + { + return this.MemberwiseClone(); + } + } } diff --git a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExportTask.cs b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExportTask.cs index 6790bf495a..b0d6f0754e 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExportTask.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExportTask.cs @@ -1,36 +1,63 @@ using System.Web; +using SmartStore.Core.Domain.Media; using SmartStore.Core.Localization; +using SmartStore.Services.Catalog; +using SmartStore.Services.Directory; using SmartStore.Services.Localization; using SmartStore.Services.Media; using SmartStore.Services.Seo; using SmartStore.Services.Tasks; +using SmartStore.Services.Tax; namespace SmartStore.Services.DataExchange.Internal { // TODO: internal really possible here because of IOC? internal partial class DataExportTask : ITask { + private readonly ICommonServices _services; private readonly IDataExporter _exporter; private readonly IExportProfileService _exportProfileService; private readonly IUrlRecordService _urlRecordService; private readonly ILocalizedEntityService _localizedEntityService; private readonly IPictureService _pictureService; - private readonly ICommonServices _services; + private readonly IPriceCalculationService _priceCalculationService; + private readonly ICurrencyService _currencyService; + private readonly ITaxService _taxService; + private readonly IPriceFormatter _priceFormatter; + private readonly ICategoryService _categoryService; + private readonly IProductAttributeParser _productAttributeParser; + + private MediaSettings _mediaSettings; public DataExportTask( + ICommonServices services, IDataExporter exporter, IExportProfileService exportProfileService, IUrlRecordService urlRecordService, ILocalizedEntityService localizedEntityService, IPictureService pictureService, - ICommonServices services) + IPriceCalculationService priceCalculationService, + ICurrencyService currencyService, + ITaxService taxService, + IPriceFormatter priceFormatter, + ICategoryService categoryService, + IProductAttributeParser productAttributeParser, + MediaSettings mediaSettings) { + _services = services; _exporter = exporter; _exportProfileService = exportProfileService; _urlRecordService = urlRecordService; _localizedEntityService = localizedEntityService; _pictureService = pictureService; - _services = services; + _priceCalculationService = priceCalculationService; + _currencyService = currencyService; + _taxService = taxService; + _priceFormatter = priceFormatter; + _categoryService = categoryService; + _productAttributeParser = productAttributeParser; + + _mediaSettings = mediaSettings; } public Localizer T { get; set; } diff --git a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExportTaskToDynamic.cs b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExportTaskToDynamic.cs index 4ebb183946..4b4e4d2f07 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExportTaskToDynamic.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExportTaskToDynamic.cs @@ -3,11 +3,13 @@ using System.Linq; using System.Linq.Expressions; using System.Reflection; +using System.Web; using SmartStore.ComponentModel; using SmartStore.Core; using SmartStore.Core.Domain.Catalog; using SmartStore.Core.Domain.Common; using SmartStore.Core.Domain.Customers; +using SmartStore.Core.Domain.DataExchange; using SmartStore.Core.Domain.Directory; using SmartStore.Core.Domain.Discounts; using SmartStore.Core.Domain.Localization; @@ -17,6 +19,8 @@ using SmartStore.Core.Domain.Seo; using SmartStore.Core.Domain.Shipping; using SmartStore.Core.Domain.Stores; +using SmartStore.Core.Html; +using SmartStore.Services.Catalog; using SmartStore.Services.Localization; using SmartStore.Services.Seo; @@ -24,6 +28,226 @@ namespace SmartStore.Services.DataExchange.Internal { internal partial class DataExportTask { + private void PrepareProductDescription(DataExportTaskContext ctx, dynamic dynObject, Product product) + { + try + { + var languageId = (ctx.Projection.LanguageId ?? 0); + string description = ""; + + // description merging + if (ctx.Projection.DescriptionMerging != ExportDescriptionMerging.None) + { + if (ctx.Projection.DescriptionMerging == ExportDescriptionMerging.ShortDescriptionOrNameIfEmpty) + { + description = dynObject.FullDescription; + + if (description.IsEmpty()) + description = dynObject.ShortDescription; + if (description.IsEmpty()) + description = dynObject.Name; + } + else if (ctx.Projection.DescriptionMerging == ExportDescriptionMerging.ShortDescription) + { + description = dynObject.ShortDescription; + } + else if (ctx.Projection.DescriptionMerging == ExportDescriptionMerging.Description) + { + description = dynObject.FullDescription; + } + else if (ctx.Projection.DescriptionMerging == ExportDescriptionMerging.NameAndShortDescription) + { + description = ((string)dynObject.Name).Grow((string)dynObject.ShortDescription, " "); + } + else if (ctx.Projection.DescriptionMerging == ExportDescriptionMerging.NameAndDescription) + { + description = ((string)dynObject.Name).Grow((string)dynObject.FullDescription, " "); + } + else if (ctx.Projection.DescriptionMerging == ExportDescriptionMerging.ManufacturerAndNameAndShortDescription || + ctx.Projection.DescriptionMerging == ExportDescriptionMerging.ManufacturerAndNameAndDescription) + { + var productManus = ctx.ProductExportContext.ProductManufacturers.Load(product.Id); + + if (productManus != null && productManus.Any()) + description = productManus.First().Manufacturer.GetLocalized(x => x.Name, languageId, true, false); + + description = description.Grow((string)dynObject.Name, " "); + + if (ctx.Projection.DescriptionMerging == ExportDescriptionMerging.ManufacturerAndNameAndShortDescription) + description = description.Grow((string)dynObject.ShortDescription, " "); + else + description = description.Grow((string)dynObject.FullDescription, " "); + } + } + else + { + description = dynObject.FullDescription; + } + + // append text + if (ctx.Projection.AppendDescriptionText.HasValue() && ((string)dynObject.ShortDescription).IsEmpty() && ((string)dynObject.FullDescription).IsEmpty()) + { + string[] appendText = ctx.Projection.AppendDescriptionText.SplitSafe(","); + if (appendText.Length > 0) + { + var rnd = (new Random()).Next(0, appendText.Length - 1); + + description = description.Grow(appendText.SafeGet(rnd), " "); + } + } + + // remove critical characters + if (description.HasValue() && ctx.Projection.RemoveCriticalCharacters) + { + foreach (var str in ctx.Projection.CriticalCharacters.SplitSafe(",")) + description = description.Replace(str, ""); + } + + // convert to plain text + if (ctx.Projection.DescriptionToPlainText) + { + //Regex reg = new Regex("<[^>]+>", RegexOptions.IgnoreCase); + //description = HttpUtility.HtmlDecode(reg.Replace(description, "")); + + description = HtmlUtils.ConvertHtmlToPlainText(description); + description = HtmlUtils.StripTags(HttpUtility.HtmlDecode(description)); + } + + dynObject.FullDescription = description; + } + catch { } + } + + private decimal? ConvertPrice(DataExportTaskContext ctx, Product product, decimal? price) + { + if (price.HasValue) + { + if (ctx.Projection.ConvertNetToGrossPrices) + { + decimal taxRate; + price = _taxService.GetProductPrice(product, price.Value, true, ctx.ContextCustomer, out taxRate); + } + + if (price != decimal.Zero) + { + price = _currencyService.ConvertFromPrimaryStoreCurrency(price.Value, ctx.ContextCurrency, ctx.Store); + } + } + return price; + } + + private decimal CalculatePrice(DataExportTaskContext ctx, Product product, bool forAttributeCombination) + { + decimal price = product.Price; + + // price type + if (ctx.Projection.PriceType.HasValue && !forAttributeCombination) + { + var priceCalculationContext = ctx.ProductExportContext as PriceCalculationContext; + + if (ctx.Projection.PriceType.Value == PriceDisplayType.LowestPrice) + { + bool displayFromMessage; + price = _priceCalculationService.GetLowestPrice(product, priceCalculationContext, out displayFromMessage); + } + else if (ctx.Projection.PriceType.Value == PriceDisplayType.PreSelectedPrice) + { + price = _priceCalculationService.GetPreselectedPrice(product, priceCalculationContext); + } + else if (ctx.Projection.PriceType.Value == PriceDisplayType.PriceWithoutDiscountsAndAttributes) + { + price = _priceCalculationService.GetFinalPrice(product, null, ctx.ContextCustomer, decimal.Zero, false, 1, null, priceCalculationContext); + } + } + + return ConvertPrice(ctx, product, price) ?? price; + } + + private void MergeWithCombination(DataExportTaskContext ctx, dynamic dynObject, Product product, + ICollection productAttributes, ProductVariantAttributeCombination combination) + { + product.MergeWithCombination(combination); + + dynObject.Price = CalculatePrice(ctx, product, combination != null); + + if (combination != null && ctx.Projection.AttributeCombinationValueMerging == ExportAttributeValueMerging.AppendAllValuesToName) + { + var values = _productAttributeParser.ParseProductVariantAttributeValues(combination.AttributesXml, productAttributes, ctx.Projection.LanguageId ?? 0); + + dynObject.Name = ((string)dynObject.Name).Grow(string.Join(", ", values), " "); + } + + dynObject._BasePriceInfo = product.GetBasePriceInfo(_services.Localization, _priceFormatter, _currencyService, _taxService, + _priceCalculationService, ctx.ContextCurrency, decimal.Zero, true); + + // navigation properties + ToDeliveryTime(ctx, dynObject, product.DeliveryTimeId); + ToQuantityUnit(ctx, dynObject, product.QuantityUnitId); + + if (ctx.Supports(ExportFeature.UsesSkuAsMpnFallback) && product.ManufacturerPartNumber.IsEmpty()) + { + dynObject.ManufacturerPartNumber = product.Sku; + } + + if (ctx.Supports(ExportFeature.OffersShippingTimeFallback)) + { + dynamic deliveryTime = dynObject.DeliveryTime; + dynObject._ShippingTime = (deliveryTime == null ? ctx.Projection.ShippingTime : deliveryTime.Name); + } + + if (ctx.Supports(ExportFeature.OffersShippingCostsFallback)) + { + dynObject._FreeShippingThreshold = ctx.Projection.FreeShippingThreshold; + + if (product.IsFreeShipping || (ctx.Projection.FreeShippingThreshold.HasValue && (decimal)dynObject.Price >= ctx.Projection.FreeShippingThreshold.Value)) + dynObject._ShippingCosts = decimal.Zero; + else + dynObject._ShippingCosts = ctx.Projection.ShippingCosts; + } + + if (ctx.Supports(ExportFeature.UsesOldPrice)) + { + if (product.OldPrice != decimal.Zero && product.OldPrice != (decimal)dynObject.Price && !(product.ProductType == ProductType.BundledProduct && product.BundlePerItemPricing)) + { + if (ctx.Projection.ConvertNetToGrossPrices) + { + decimal taxRate; + dynObject._OldPrice = _taxService.GetProductPrice(product, product.OldPrice, true, ctx.ContextCustomer, out taxRate); + } + else + { + dynObject._OldPrice = product.OldPrice; + } + } + else + { + dynObject._OldPrice = null; + } + } + + if (ctx.Supports(ExportFeature.UsesSpecialPrice)) + { + dynObject._SpecialPrice = null; + dynObject._RegularPrice = null; // price if a special price would not exist + + if (!(product.ProductType == ProductType.BundledProduct && product.BundlePerItemPricing)) + { + var specialPrice = _priceCalculationService.GetSpecialPrice(product); + + dynObject._SpecialPrice = ConvertPrice(ctx, product, specialPrice); + + if (specialPrice.HasValue) + { + decimal tmpSpecialPrice = product.SpecialPrice.Value; + product.SpecialPrice = null; + dynObject._RegularPrice = CalculatePrice(ctx, product, combination != null); + product.SpecialPrice = tmpSpecialPrice; + } + } + } + } + + private List GetLocalized(DataExportTaskContext ctx, T entity, params Expression>[] keySelectors) where T : BaseEntity, ILocalizedEntity { @@ -145,14 +369,6 @@ private dynamic ToDynamic(DataExportTaskContext ctx, RewardPointsHistory points) dynamic result = new DynamicEntity(points); - result.Id = points.Id; - result.CustomerId = points.CustomerId; - result.Points = points.Points; - result.PointsBalance = points.PointsBalance; - result.UsedAmount = points.UsedAmount; - result.Message = points.Message; - result.CreatedOnUtc = points.CreatedOnUtc; - return result; } @@ -163,25 +379,6 @@ private dynamic ToDynamic(DataExportTaskContext ctx, Customer customer) dynamic result = new DynamicEntity(customer); - result.Id = customer.Id; - result.CustomerGuid = customer.CustomerGuid; - result.Username = customer.Username; - result.Email = customer.Email; - result.Password = customer.Password; // not so good but referenced in Excel export - result.PasswordFormatId = customer.PasswordFormatId; - result.PasswordSalt = customer.PasswordSalt; - result.AdminComment = customer.AdminComment; - result.IsTaxExempt = customer.IsTaxExempt; - result.AffiliateId = customer.AffiliateId; - result.Active = customer.Active; - result.Deleted = customer.Deleted; - result.IsSystemAccount = customer.IsSystemAccount; - result.SystemName = customer.SystemName; - result.LastIpAddress = customer.LastIpAddress; - result.CreatedOnUtc = customer.CreatedOnUtc; - result.LastLoginDateUtc = customer.LastLoginDateUtc; - result.LastActivityDateUtc = customer.LastActivityDateUtc; - result.BillingAddress = null; result.ShippingAddress = null; result.Addresses = null; @@ -203,19 +400,6 @@ private dynamic ToDynamic(DataExportTaskContext ctx, Store store) dynamic result = new DynamicEntity(store); - result.Id = store.Id; - result.Name = store.Name; - result.Url = store.Url; - result.SslEnabled = store.SslEnabled; - result.SecureUrl = store.SecureUrl; - result.Hosts = store.Hosts; - result.LogoPictureId = store.LogoPictureId; - result.DisplayOrder = store.DisplayOrder; - result.HtmlBodyId = store.HtmlBodyId; - result.ContentDeliveryNetwork = store.ContentDeliveryNetwork; - result.PrimaryStoreCurrencyId = store.PrimaryStoreCurrencyId; - result.PrimaryExchangeRateCurrencyId = store.PrimaryExchangeRateCurrencyId; - result.PrimaryStoreCurrency = ToDynamic(ctx, store.PrimaryStoreCurrency); result.PrimaryExchangeRateCurrency = ToDynamic(ctx, store.PrimaryExchangeRateCurrency); @@ -229,12 +413,7 @@ private dynamic ToDynamic(DataExportTaskContext ctx, DeliveryTime deliveryTime) dynamic result = new DynamicEntity(deliveryTime); - result.Id = deliveryTime.Id; result.Name = deliveryTime.GetLocalized(x => x.Name, ctx.Projection.LanguageId ?? 0, true, false); - result.DisplayLocale = deliveryTime.DisplayLocale; - result.ColorHexValue = deliveryTime.ColorHexValue; - result.DisplayOrder = deliveryTime.DisplayOrder; - result._Localized = GetLocalized(ctx, deliveryTime, x => x.Name); return result; @@ -258,12 +437,8 @@ private dynamic ToDynamic(DataExportTaskContext ctx, QuantityUnit quantityUnit) dynamic result = new DynamicEntity(quantityUnit); - result.Id = quantityUnit.Id; result.Name = quantityUnit.GetLocalized(x => x.Name, ctx.Projection.LanguageId ?? 0, true, false); result.Description = quantityUnit.GetLocalized(x => x.Description, ctx.Projection.LanguageId ?? 0, true, false); - result.DisplayLocale = quantityUnit.DisplayLocale; - result.DisplayOrder = quantityUnit.DisplayOrder; - result.IsDefault = quantityUnit.IsDefault; result._Localized = GetLocalized(ctx, quantityUnit, x => x.Name, @@ -290,10 +465,6 @@ private dynamic ToDynamic(DataExportTaskContext ctx, Picture picture, int thumbP dynamic result = new DynamicEntity(picture); - result.Id = picture.Id; - result.SeoFilename = picture.SeoFilename; - result.MimeType = picture.MimeType; - result._ThumbImageUrl = _pictureService.GetPictureUrl(picture, thumbPictureSize, false, ctx.Store.Url); result._ImageUrl = _pictureService.GetPictureUrl(picture, detailsPictureSize, false, ctx.Store.Url); result._FullSizeImageUrl = _pictureService.GetPictureUrl(picture, 0, false, ctx.Store.Url); @@ -313,16 +484,8 @@ private dynamic ToDynamic(DataExportTaskContext ctx, ProductVariantAttribute pva dynamic result = new DynamicEntity(pva); - result.Id = pva.Id; - result.TextPrompt = pva.TextPrompt; - result.IsRequired = pva.IsRequired; - result.AttributeControlTypeId = pva.AttributeControlTypeId; - result.DisplayOrder = pva.DisplayOrder; - dynamic attribute = new DynamicEntity(pva.ProductAttribute); - attribute.Id = pva.ProductAttribute.Id; - attribute.Alias = pva.ProductAttribute.Alias; attribute.Name = pva.ProductAttribute.GetLocalized(x => x.Name, ctx.Projection.LanguageId ?? 0, true, false); attribute.Description = pva.ProductAttribute.GetLocalized(x => x.Description, ctx.Projection.LanguageId ?? 0, true, false); @@ -330,23 +493,12 @@ private dynamic ToDynamic(DataExportTaskContext ctx, ProductVariantAttribute pva .OrderBy(x => x.DisplayOrder) .Select(x => { - dynamic value = new DynamicEntity(x); - - value.Id = x.Id; - value.Alias = x.Alias; - value.Name = x.GetLocalized(y => y.Name, ctx.Projection.LanguageId ?? 0, true, false); - value.ColorSquaresRgb = x.ColorSquaresRgb; - value.PriceAdjustment = x.PriceAdjustment; - value.WeightAdjustment = x.WeightAdjustment; - value.IsPreSelected = x.IsPreSelected; - value.DisplayOrder = x.DisplayOrder; - value.ValueTypeId = x.ValueTypeId; - value.LinkedProductId = x.LinkedProductId; - value.Quantity = x.Quantity; - - value._Localized = GetLocalized(ctx, x, y => y.Name); - - return value; + dynamic dyn = new DynamicEntity(x); + + dyn.Name = x.GetLocalized(y => y.Name, ctx.Projection.LanguageId ?? 0, true, false); + dyn._Localized = GetLocalized(ctx, x, y => y.Name); + + return dyn; }) .ToList(); @@ -474,74 +626,7 @@ private dynamic ToDynamic(DataExportTaskContext ctx, Order order) dynamic result = new DynamicEntity(order); - result.Id = order.Id; result.OrderNumber = order.GetOrderNumber(); - result.OrderGuid = order.OrderGuid; - result.StoreId = order.StoreId; - result.CustomerId = order.CustomerId; - result.BillingAddressId = order.BillingAddressId; - result.ShippingAddressId = order.ShippingAddressId; - result.OrderStatusId = order.OrderStatusId; - result.ShippingStatusId = order.ShippingStatusId; - result.PaymentStatusId = order.PaymentStatusId; - result.PaymentMethodSystemName = order.PaymentMethodSystemName; - result.CustomerCurrencyCode = order.CustomerCurrencyCode; - result.CurrencyRate = order.CurrencyRate; - result.CustomerTaxDisplayTypeId = order.CustomerTaxDisplayTypeId; - result.VatNumber = order.VatNumber; - result.OrderSubtotalInclTax = order.OrderSubtotalInclTax; - result.OrderSubtotalExclTax = order.OrderSubtotalExclTax; - result.OrderSubTotalDiscountInclTax = order.OrderSubTotalDiscountInclTax; - result.OrderSubTotalDiscountExclTax = order.OrderSubTotalDiscountExclTax; - result.OrderShippingInclTax = order.OrderShippingInclTax; - result.OrderShippingExclTax = order.OrderShippingExclTax; - result.OrderShippingTaxRate = order.OrderShippingTaxRate; - result.PaymentMethodAdditionalFeeInclTax = order.PaymentMethodAdditionalFeeInclTax; - result.PaymentMethodAdditionalFeeExclTax = order.PaymentMethodAdditionalFeeExclTax; - result.PaymentMethodAdditionalFeeTaxRate = order.PaymentMethodAdditionalFeeTaxRate; - result.TaxRates = order.TaxRates; - result.OrderTax = order.OrderTax; - result.OrderDiscount = order.OrderDiscount; - result.OrderTotal = order.OrderTotal; - result.RefundedAmount = order.RefundedAmount; - result.RewardPointsWereAdded = order.RewardPointsWereAdded; - result.CheckoutAttributeDescription = order.CheckoutAttributeDescription; - result.CheckoutAttributesXml = order.CheckoutAttributesXml; - result.CustomerLanguageId = order.CustomerLanguageId; - result.AffiliateId = order.AffiliateId; - result.CustomerIp = order.CustomerIp; - result.AllowStoringCreditCardNumber = order.AllowStoringCreditCardNumber; - result.CardType = order.CardType; - result.CardName = order.CardName; - result.CardNumber = order.CardNumber; - result.MaskedCreditCardNumber = order.MaskedCreditCardNumber; - result.CardCvv2 = order.CardCvv2; - result.CardExpirationMonth = order.CardExpirationMonth; - result.CardExpirationYear = order.CardExpirationYear; - result.AllowStoringDirectDebit = order.AllowStoringDirectDebit; - result.DirectDebitAccountHolder = order.DirectDebitAccountHolder; - result.DirectDebitAccountNumber = order.DirectDebitAccountNumber; - result.DirectDebitBankCode = order.DirectDebitBankCode; - result.DirectDebitBankName = order.DirectDebitBankName; - result.DirectDebitBIC = order.DirectDebitBIC; - result.DirectDebitCountry = order.DirectDebitCountry; - result.DirectDebitIban = order.DirectDebitIban; - result.CustomerOrderComment = order.CustomerOrderComment; - result.AuthorizationTransactionId = order.AuthorizationTransactionId; - result.AuthorizationTransactionCode = order.AuthorizationTransactionCode; - result.AuthorizationTransactionResult = order.AuthorizationTransactionResult; - result.CaptureTransactionId = order.CaptureTransactionId; - result.CaptureTransactionResult = order.CaptureTransactionResult; - result.SubscriptionTransactionId = order.SubscriptionTransactionId; - result.PurchaseOrderNumber = order.PurchaseOrderNumber; - result.PaidDateUtc = order.PaidDateUtc; - result.ShippingMethod = order.ShippingMethod; - result.ShippingRateComputationMethodSystemName = order.ShippingRateComputationMethodSystemName; - result.Deleted = order.Deleted; - result.CreatedOnUtc = order.CreatedOnUtc; - result.UpdatedOnUtc = order.UpdatedOnUtc; - result.RewardPointsRemaining = order.RewardPointsRemaining; - result.HasNewPaymentNotification = order.HasNewPaymentNotification; result.OrderStatus = order.OrderStatus.GetLocalizedEnum(_services.Localization, ctx.Projection.LanguageId ?? 0); result.PaymentStatus = order.PaymentStatus.GetLocalizedEnum(_services.Localization, ctx.Projection.LanguageId ?? 0); result.ShippingStatus = order.ShippingStatus.GetLocalizedEnum(_services.Localization, ctx.Projection.LanguageId ?? 0); @@ -551,6 +636,7 @@ private dynamic ToDynamic(DataExportTaskContext ctx, Order order) result.ShippingAddress = null; result.Store = null; result.Shipments = null; + result.RedeemedRewardPointsEntry = ToDynamic(ctx, order.RedeemedRewardPointsEntry); return result; @@ -563,27 +649,6 @@ private dynamic ToDynamic(DataExportTaskContext ctx, OrderItem orderItem) dynamic result = new DynamicEntity(orderItem); - result.Id = orderItem.Id; - result.OrderItemGuid = orderItem.OrderItemGuid; - result.OrderId = orderItem.OrderId; - result.ProductId = orderItem.ProductId; - result.Quantity = orderItem.Quantity; - result.UnitPriceInclTax = orderItem.UnitPriceInclTax; - result.UnitPriceExclTax = orderItem.UnitPriceExclTax; - result.PriceInclTax = orderItem.PriceInclTax; - result.PriceExclTax = orderItem.PriceExclTax; - result.TaxRate = orderItem.TaxRate; - result.DiscountAmountInclTax = orderItem.DiscountAmountInclTax; - result.DiscountAmountExclTax = orderItem.DiscountAmountExclTax; - result.AttributeDescription = orderItem.AttributeDescription; - result.AttributesXml = orderItem.AttributesXml; - result.DownloadCount = orderItem.DownloadCount; - result.IsDownloadActivated = orderItem.IsDownloadActivated; - result.LicenseDownloadId = orderItem.LicenseDownloadId; - result.ItemWeight = orderItem.ItemWeight; - result.BundleData = orderItem.BundleData; - result.ProductCost = orderItem.ProductCost; - result.Product = ToDynamic(ctx, orderItem.Product); return result; @@ -596,24 +661,11 @@ private dynamic ToDynamic(DataExportTaskContext ctx, Shipment shipment) dynamic result = new DynamicEntity(shipment); - result.Id = shipment.Id; - result.OrderId = shipment.OrderId; - result.TrackingNumber = shipment.TrackingNumber; - result.TotalWeight = shipment.TotalWeight; - result.ShippedDateUtc = shipment.ShippedDateUtc; - result.DeliveryDateUtc = shipment.DeliveryDateUtc; - result.CreatedOnUtc = shipment.CreatedOnUtc; - result.ShipmentItems = shipment.ShipmentItems .Select(x => { dynamic exp = new DynamicEntity(x); - exp.Id = x.Id; - exp.ShipmentId = x.ShipmentId; - exp.OrderItemId = x.OrderItemId; - exp.Quantity = x.Quantity; - return exp; }) .ToList(); @@ -628,19 +680,6 @@ private dynamic ToDynamic(DataExportTaskContext ctx, Discount discount) dynamic result = new DynamicEntity(discount); - result.Id = discount.Id; - result.Name = discount.Name; - result.DiscountTypeId = discount.DiscountTypeId; - result.UsePercentage = discount.UsePercentage; - result.DiscountPercentage = discount.DiscountPercentage; - result.DiscountAmount = discount.DiscountAmount; - result.StartDateUtc = discount.StartDateUtc; - result.EndDateUtc = discount.EndDateUtc; - result.RequiresCouponCode = discount.RequiresCouponCode; - result.CouponCode = discount.CouponCode; - result.DiscountLimitationId = discount.DiscountLimitationId; - result.LimitationTimes = discount.LimitationTimes; - return result; } @@ -653,27 +692,16 @@ private dynamic ToDynamic(DataExportTaskContext ctx, ProductSpecificationAttribu dynamic result = new DynamicEntity(psa); - result.Id = psa.Id; - result.ProductId = psa.ProductId; - result.SpecificationAttributeOptionId = psa.SpecificationAttributeOptionId; - result.AllowFiltering = psa.AllowFiltering; - result.ShowOnProductPage = psa.ShowOnProductPage; - result.DisplayOrder = psa.DisplayOrder; - dynamic dynAttribute = new DynamicEntity(option.SpecificationAttribute); - dynAttribute.Id = option.SpecificationAttribute.Id; dynAttribute.Name = option.SpecificationAttribute.GetLocalized(x => x.Name, ctx.Projection.LanguageId ?? 0, true, false); - dynAttribute.DisplayOrder = option.SpecificationAttribute.DisplayOrder; dynAttribute._Localized = GetLocalized(ctx, option.SpecificationAttribute, x => x.Name); dynamic dynOption = new DynamicEntity(option); - dynOption.Id = option.Id; - dynOption.SpecificationAttributeId = option.SpecificationAttributeId; dynOption.Name = option.GetLocalized(x => x.Name, ctx.Projection.LanguageId ?? 0, true, false); - dynOption.DisplayOrder = option.DisplayOrder; dynOption._Localized = GetLocalized(ctx, option, x => x.Name); + dynOption.SpecificationAttribute = dynAttribute; result.SpecificationAttributeOption = dynOption; @@ -688,13 +716,6 @@ private dynamic ToDynamic(DataExportTaskContext ctx, GenericAttribute genericAtt dynamic result = new DynamicEntity(genericAttribute); - result.Id = genericAttribute.Id; - result.EntityId = genericAttribute.EntityId; - result.KeyGroup = genericAttribute.KeyGroup; - result.Key = genericAttribute.Key; - result.Value = genericAttribute.Value; - result.StoreId = genericAttribute.StoreId; - return result; } @@ -705,15 +726,430 @@ private dynamic ToDynamic(DataExportTaskContext ctx, NewsLetterSubscription subs dynamic result = new DynamicEntity(subscription); - result.Id = subscription.Id; - result.NewsLetterSubscriptionGuid = subscription.NewsLetterSubscriptionGuid; - result.Email = subscription.Email; - result.Active = subscription.Active; - result.CreatedOnUtc = subscription.CreatedOnUtc; - result.StoreId = subscription.StoreId; + return result; + } + + + private List Convert(DataExportTaskContext ctx, Product product) + { + var result = new List(); + + var languageId = (ctx.Projection.LanguageId ?? 0); + var productTemplate = ctx.ProductTemplates.FirstOrDefault(x => x.Key == product.ProductTemplateId); + var pictureSize = _mediaSettings.ProductDetailsPictureSize; + + if (ctx.Supports(ExportFeature.CanIncludeMainPicture) && ctx.Projection.PictureSize > 0) + pictureSize = ctx.Projection.PictureSize; + + var perfLoadId = (ctx.IsPreview ? 0 : product.Id); // perf preview (it's a compromise) + var productPictures = ctx.ProductExportContext.ProductPictures.Load(perfLoadId); + var productManufacturers = ctx.ProductExportContext.ProductManufacturers.Load(perfLoadId); + var productCategories = ctx.ProductExportContext.ProductCategories.Load(product.Id); + var productAttributes = ctx.ProductExportContext.Attributes.Load(product.Id); + var productAttributeCombinations = ctx.ProductExportContext.AttributeCombinations.Load(product.Id); + var productTags = ctx.ProductExportContext.ProductTags.Load(perfLoadId); + var specificationAttributes = ctx.ProductExportContext.ProductSpecificationAttributes.Load(perfLoadId); + + dynamic dynObject = ToDynamic(ctx, product); + + #region gerneral data + + dynObject._ProductTemplateViewPath = (productTemplate.Value == null ? "" : productTemplate.Value.ViewPath); + + dynObject._DetailUrl = ctx.Store.Url.EnsureEndsWith("/") + (string)dynObject.SeName; + + dynObject._CategoryName = null; + + if (ctx.Categories.Count > 0 && ctx.CategoryPathes.Count > 0) + { + dynObject._CategoryPath = _categoryService.GetCategoryPath( + product, + null, + x => ctx.CategoryPathes.ContainsKey(x) ? ctx.CategoryPathes[x] : null, + (id, value) => ctx.CategoryPathes[id] = value, + x => ctx.Categories.ContainsKey(x) ? ctx.Categories[x] : _categoryService.GetCategoryById(x), + productCategories.OrderBy(x => x.DisplayOrder).FirstOrDefault() + ); + } + else + { + dynObject._CategoryPath = null; + } + + dynObject.ProductPictures = productPictures + .OrderBy(x => x.DisplayOrder) + .Select(x => + { + dynamic dyn = new DynamicEntity(x); + + dyn.Picture = ToDynamic(ctx, x.Picture, _mediaSettings.ProductThumbPictureSize, pictureSize); + + return dyn; + }) + .ToList(); + + dynObject.ProductManufacturers = productManufacturers + .OrderBy(x => x.DisplayOrder) + .Select(x => + { + dynamic dyn = new DynamicEntity(x); + + dyn.Manufacturer = ToDynamic(ctx, x.Manufacturer); + + if (x.Manufacturer != null && x.Manufacturer.PictureId.HasValue) + dyn.Manufacturer.Picture = ToDynamic(ctx, x.Manufacturer.Picture, _mediaSettings.ManufacturerThumbPictureSize, _mediaSettings.ManufacturerThumbPictureSize); + else + dyn.Manufacturer.Picture = null; + + return dyn; + }) + .ToList(); + + dynObject.ProductCategories = productCategories + .OrderBy(x => x.DisplayOrder) + .Select(x => + { + dynamic dyn = new DynamicEntity(x); + + dyn.Category = ToDynamic(ctx, x.Category); + + if (x.Category != null && x.Category.PictureId.HasValue) + dyn.Category.Picture = ToDynamic(ctx, x.Category.Picture, _mediaSettings.CategoryThumbPictureSize, _mediaSettings.CategoryThumbPictureSize); + + if (dynObject._CategoryName == null) + dynObject._CategoryName = (string)dyn.Category.Name; + + return dyn; + }) + .ToList(); + + dynObject.ProductAttributes = productAttributes + .OrderBy(x => x.DisplayOrder) + .Select(x => ToDynamic(ctx, x)) + .ToList(); + + dynObject.ProductAttributeCombinations = productAttributeCombinations + .Select(x => + { + dynamic dyn = ToDynamic(ctx, x); + var assignedPictures = new List(); + + foreach (int pictureId in x.GetAssignedPictureIds()) + { + var assignedPicture = productPictures.FirstOrDefault(y => y.PictureId == pictureId); + if (assignedPicture != null && assignedPicture.Picture != null) + { + assignedPictures.Add(ToDynamic(ctx, assignedPicture.Picture, _mediaSettings.ProductThumbPictureSize, pictureSize)); + } + } + + dyn.Pictures = assignedPictures; + + return dyn; + }) + .ToList(); + + if (product.HasTierPrices) + { + var tierPrices = ctx.ProductExportContext.TierPrices.Load(product.Id) + .RemoveDuplicatedQuantities(); + + dynObject.TierPrices = tierPrices + .Select(x => + { + dynamic dyn = new DynamicEntity(x); + + return dyn; + }) + .ToList(); + } + + if (product.HasDiscountsApplied) + { + var appliedDiscounts = ctx.ProductExportContext.AppliedDiscounts.Load(product.Id); + + dynObject.AppliedDiscounts = appliedDiscounts + .Select(x => ToDynamic(ctx, x)) + .ToList(); + } + + dynObject.ProductTags = productTags + .Select(x => + { + dynamic dyn = new DynamicEntity(x); + + dyn.Name = x.GetLocalized(y => y.Name, languageId, true, false); + dyn.SeName = x.GetSeName(languageId); + dyn._Localized = GetLocalized(ctx, x, y => y.Name); + + return dyn; + }) + .ToList(); + + dynObject.ProductSpecificationAttributes = specificationAttributes + .Select(x => ToDynamic(ctx, x)) + .ToList(); + + if (product.ProductType == ProductType.BundledProduct) + { + var bundleItems = ctx.ProductExportContext.ProductBundleItems.Load(perfLoadId); + + dynObject.ProductBundleItems = bundleItems + .Select(x => + { + dynamic dyn = new DynamicEntity(x); + + dyn.Name = x.GetLocalized(y => y.Name, languageId, true, false); + dyn.ShortDescription = x.GetLocalized(y => y.ShortDescription, languageId, true, false); + dyn._Localized = GetLocalized(ctx, x, y => y.Name, y => y.ShortDescription); + + return dyn; + }) + .ToList(); + } + + #endregion + + #region more attribute controlled data + + if (ctx.Supports(ExportFeature.CanProjectDescription)) + { + PrepareProductDescription(ctx, dynObject, product); + } + + if (ctx.Supports(ExportFeature.OffersBrandFallback)) + { + string brand = null; + var productManus = ctx.ProductExportContext.ProductManufacturers.Load(perfLoadId); + + if (productManus != null && productManus.Any()) + brand = productManus.First().Manufacturer.GetLocalized(x => x.Name, languageId, true, false); + + if (brand.IsEmpty()) + brand = ctx.Projection.Brand; + + dynObject._Brand = brand; + } + + if (ctx.Supports(ExportFeature.CanIncludeMainPicture)) + { + if (productPictures != null && productPictures.Any()) + dynObject._MainPictureUrl = _pictureService.GetPictureUrl(productPictures.First().Picture, ctx.Projection.PictureSize, storeLocation: ctx.Store.Url); + else + dynObject._MainPictureUrl = _pictureService.GetDefaultPictureUrl(ctx.Projection.PictureSize, storeLocation: ctx.Store.Url); + } + + #endregion + + if (!ctx.IsPreview && ctx.Projection.AttributeCombinationAsProduct && productAttributeCombinations.Where(x => x.IsActive).Count() > 0) + { + // EF does not support entities to be constructed in a LINQ to entities query. + // So it's not possible to join-query attribute combinations and products without losing ProductSearchContext ability. + // We are reduced to somewhat compound data here. + + foreach (var combination in productAttributeCombinations.Where(x => x.IsActive)) + { + // TODO: Das ist nocht nicht zu Ende gedacht, wegen MergeWithCombination etc. + //var clone = new ExpandoObject(); + //clone.Merge((IDictionary)dynObject); + //matterOfDataMerging(clone, combination); + //result.Add(clone); + + // TODO: das hier ist besser. Aber ein Product-Klon muss immer noch erstellt werden. + //var clone = new DynamicEntity((DynamicEntity)dynObject); + //matterOfDataMerging(clone, combination); + //result.Add(clone); + + var productClone = product.Clone(); + var dyn = new DynamicEntity(productClone); + MergeWithCombination(ctx, dyn, productClone, productAttributes, combination); + result.Add(dyn); + } + } + else + { + MergeWithCombination(ctx, dynObject, product, productAttributes, null); + result.Add(dynObject); + } return result; } + private List Convert(DataExportTaskContext ctx, Order order) + { + var result = new List(); + + ctx.OrderExportContext.Addresses.Collect(order.ShippingAddressId ?? 0); + + var perfLoadId = (ctx.IsPreview ? 0 : order.Id); + var addresses = ctx.OrderExportContext.Addresses.Load(ctx.IsPreview ? 0 : order.BillingAddressId); + var customers = ctx.OrderExportContext.Customers.Load(order.CustomerId); + var rewardPointsHistories = ctx.OrderExportContext.RewardPointsHistories.Load(ctx.IsPreview ? 0 : order.CustomerId); + var orderItems = ctx.OrderExportContext.OrderItems.Load(perfLoadId); + var shipments = ctx.OrderExportContext.Shipments.Load(perfLoadId); + + dynamic dynObject = ToDynamic(ctx, order); + + if (ctx.Stores.ContainsKey(order.StoreId)) + { + dynObject.Store = ToDynamic(ctx, ctx.Stores[order.StoreId]); + } + + dynObject.Customer = ToDynamic(ctx, customers.FirstOrDefault(x => x.Id == order.CustomerId)); + + dynObject.Customer.RewardPointsHistory = rewardPointsHistories + .Select(x => ToDynamic(ctx, x)) + .ToList(); + + if (rewardPointsHistories.Count > 0) + { + dynObject.Customer._RewardPointsBalance = rewardPointsHistories + .OrderByDescending(x => x.CreatedOnUtc) + .ThenByDescending(x => x.Id) + .FirstOrDefault() + .PointsBalance; + } + + dynObject.BillingAddress = ToDynamic(ctx, addresses.FirstOrDefault(x => x.Id == order.BillingAddressId)); + + if (order.ShippingAddressId.HasValue) + { + dynObject.ShippingAddress = ToDynamic(ctx, addresses.FirstOrDefault(x => x.Id == order.ShippingAddressId.Value)); + } + + dynObject.OrderItems = orderItems + .Select(e => + { + dynamic dyn = ToDynamic(ctx, e); + var productTemplate = ctx.ProductTemplates.FirstOrDefault(x => x.Key == e.Product.ProductTemplateId); + + dyn.Product._ProductTemplateViewPath = (productTemplate.Value == null ? "" : productTemplate.Value.ViewPath); + + dyn.Product._BasePriceInfo = e.Product.GetBasePriceInfo(_services.Localization, _priceFormatter, _currencyService, _taxService, + _priceCalculationService, ctx.ContextCurrency, decimal.Zero, true); + + ToDeliveryTime(ctx, dyn.Product, e.Product.DeliveryTimeId); + ToQuantityUnit(ctx, dyn.Product, e.Product.QuantityUnitId); + + return dyn; + }) + .ToList(); + + dynObject.Shipments = shipments + .Select(x => ToDynamic(ctx, x)) + .ToList(); + + result.Add(dynObject); + + return result; + } + + private List Convert(DataExportTaskContext ctx, Manufacturer manufacturer) + { + var result = new List(); + + var productManufacturers = ctx.ManufacturerExportContext.ProductManufacturers.Load(manufacturer.Id); + + dynamic dynObject = ToDynamic(ctx, manufacturer); + + if (!ctx.IsPreview && manufacturer.PictureId.HasValue) + { + var pictures = ctx.ManufacturerExportContext.Pictures.Load(manufacturer.PictureId.Value); + + if (pictures.Count > 0) + dynObject.Picture = ToDynamic(ctx, pictures.First(), _mediaSettings.ManufacturerThumbPictureSize, _mediaSettings.ManufacturerThumbPictureSize); + } + + dynObject.ProductManufacturers = productManufacturers + .OrderBy(x => x.DisplayOrder) + .Select(x => + { + dynamic dyn = new DynamicEntity(x); + + return dyn; + }) + .ToList(); + + result.Add(dynObject); + + return result; + } + + private List Convert(DataExportTaskContext ctx, Category category) + { + var result = new List(); + + var productCategories = ctx.CategoryExportContext.ProductCategories.Load(category.Id); + + dynamic dynObject = ToDynamic(ctx, category); + + if (!ctx.IsPreview && category.PictureId.HasValue) + { + var pictures = ctx.CategoryExportContext.Pictures.Load(category.PictureId.Value); + + if (pictures.Count > 0) + dynObject.Picture = ToDynamic(ctx, pictures.First(), _mediaSettings.CategoryThumbPictureSize, _mediaSettings.CategoryThumbPictureSize); + } + + dynObject.ProductCategories = productCategories + .OrderBy(x => x.DisplayOrder) + .Select(x => + { + dynamic dyn = new DynamicEntity(x); + + return dyn; + }) + .ToList(); + + result.Add(dynObject); + + return result; + } + + private List Convert(DataExportTaskContext ctx, Customer customer) + { + var result = new List(); + + var perfLoadId = (ctx.IsPreview ? 0 : customer.Id); + var genericAttributes = ctx.CustomerExportContext.GenericAttributes.Load(perfLoadId); + + dynamic dynObject = ToDynamic(ctx, customer); + + dynObject.BillingAddress = ToDynamic(ctx, customer.BillingAddress); + dynObject.ShippingAddress = ToDynamic(ctx, customer.ShippingAddress); + + dynObject.Addresses = customer.Addresses + .Select(x => ToDynamic(ctx, x)) + .ToList(); + + dynObject.CustomerRoles = customer.CustomerRoles + .Select(x => + { + dynamic dyn = new DynamicEntity(x); + + return dyn; + }) + .ToList(); + + dynObject._GenericAttributes = genericAttributes + .Select(x => ToDynamic(ctx, x)) + .ToList(); + + dynObject._HasNewsletterSubscription = ctx.NewsletterSubscriptions.Contains(customer.Email, StringComparer.CurrentCultureIgnoreCase); + + result.Add(dynObject); + + return result; + } + + private List Convert(DataExportTaskContext ctx, NewsLetterSubscription subscription) + { + var result = new List(); + + dynamic dynObject = ToDynamic(ctx, subscription); + + result.Add(dynObject); + return result; + } } } From 4b6946a3af608ef01266c8974e7cd7ed847a47f9 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Tue, 10 Nov 2015 19:49:26 +0100 Subject: [PATCH 011/626] Moved export code from ITask to IDataExporter implementation --- .../DataExchange/IDataExporter.cs | 10 +- .../DataExchange/Internal/DataExportTask.cs | 46 +--- .../DataExchange/Internal/DataExporter.cs | 238 ++++++++++++++++++ ...kToDynamic.cs => DataExporterToDynamic.cs} | 2 +- .../SmartStore.Services.csproj | 3 +- 5 files changed, 247 insertions(+), 52 deletions(-) create mode 100644 src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporter.cs rename src/Libraries/SmartStore.Services/DataExchange/Internal/{DataExportTaskToDynamic.cs => DataExporterToDynamic.cs} (99%) diff --git a/src/Libraries/SmartStore.Services/DataExchange/IDataExporter.cs b/src/Libraries/SmartStore.Services/DataExchange/IDataExporter.cs index 036fa99739..82820238d8 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/IDataExporter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/IDataExporter.cs @@ -1,11 +1,8 @@ -using SmartStore.Core.Domain; -using SmartStore.Core.Plugins; -using System; +using System; using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Threading; -using System.Threading.Tasks; +using SmartStore.Core.Domain; +using SmartStore.Core.Plugins; namespace SmartStore.Services.DataExchange { @@ -23,6 +20,7 @@ public interface IDataExporter long GetDataCount(DataExportRequest request); } + public class DataExportRequest { private readonly static ProgressSetter _voidProgressSetter = DataExportRequest.SetProgress; diff --git a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExportTask.cs b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExportTask.cs index b0d6f0754e..e151674022 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExportTask.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExportTask.cs @@ -1,63 +1,20 @@ using System.Web; -using SmartStore.Core.Domain.Media; using SmartStore.Core.Localization; -using SmartStore.Services.Catalog; -using SmartStore.Services.Directory; -using SmartStore.Services.Localization; -using SmartStore.Services.Media; -using SmartStore.Services.Seo; using SmartStore.Services.Tasks; -using SmartStore.Services.Tax; namespace SmartStore.Services.DataExchange.Internal { - // TODO: internal really possible here because of IOC? internal partial class DataExportTask : ITask { - private readonly ICommonServices _services; private readonly IDataExporter _exporter; private readonly IExportProfileService _exportProfileService; - private readonly IUrlRecordService _urlRecordService; - private readonly ILocalizedEntityService _localizedEntityService; - private readonly IPictureService _pictureService; - private readonly IPriceCalculationService _priceCalculationService; - private readonly ICurrencyService _currencyService; - private readonly ITaxService _taxService; - private readonly IPriceFormatter _priceFormatter; - private readonly ICategoryService _categoryService; - private readonly IProductAttributeParser _productAttributeParser; - - private MediaSettings _mediaSettings; public DataExportTask( - ICommonServices services, IDataExporter exporter, - IExportProfileService exportProfileService, - IUrlRecordService urlRecordService, - ILocalizedEntityService localizedEntityService, - IPictureService pictureService, - IPriceCalculationService priceCalculationService, - ICurrencyService currencyService, - ITaxService taxService, - IPriceFormatter priceFormatter, - ICategoryService categoryService, - IProductAttributeParser productAttributeParser, - MediaSettings mediaSettings) + IExportProfileService exportProfileService) { - _services = services; _exporter = exporter; _exportProfileService = exportProfileService; - _urlRecordService = urlRecordService; - _localizedEntityService = localizedEntityService; - _pictureService = pictureService; - _priceCalculationService = priceCalculationService; - _currencyService = currencyService; - _taxService = taxService; - _priceFormatter = priceFormatter; - _categoryService = categoryService; - _productAttributeParser = productAttributeParser; - - _mediaSettings = mediaSettings; } public Localizer T { get; set; } @@ -85,6 +42,7 @@ public void Execute(TaskExecutionContext ctx) { ctx.SetProgress(val, max, msg); }; + if (selectedEntityIds.HasValue()) { request.EntitiesToExport = selectedEntityIds.ToIntArray(); diff --git a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporter.cs b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporter.cs new file mode 100644 index 0000000000..aa0a07f44f --- /dev/null +++ b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporter.cs @@ -0,0 +1,238 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Web; +using SmartStore.Core.Domain.Catalog; +using SmartStore.Core.Domain.DataExchange; +using SmartStore.Core.Domain.Media; +using SmartStore.Core.Domain.Messages; +using SmartStore.Core.Localization; +using SmartStore.Services.Catalog; +using SmartStore.Services.Directory; +using SmartStore.Services.Helpers; +using SmartStore.Services.Localization; +using SmartStore.Services.Media; +using SmartStore.Services.Seo; +using SmartStore.Services.Tasks; +using SmartStore.Services.Tax; + +namespace SmartStore.Services.DataExchange.Internal +{ + internal partial class DataExporter : IDataExporter + { + private static readonly ReaderWriterLockSlim _rwLock = new ReaderWriterLockSlim(); + + private readonly ICommonServices _services; + private readonly IUrlRecordService _urlRecordService; + private readonly ILocalizedEntityService _localizedEntityService; + private readonly IPictureService _pictureService; + private readonly IPriceCalculationService _priceCalculationService; + private readonly ICurrencyService _currencyService; + private readonly ITaxService _taxService; + private readonly IPriceFormatter _priceFormatter; + private readonly ICategoryService _categoryService; + private readonly IProductAttributeParser _productAttributeParser; + private readonly IProductService _productService; + private readonly IDateTimeHelper _dateTimeHelper; + + private MediaSettings _mediaSettings; + + public DataExporter( + ICommonServices services, + IUrlRecordService urlRecordService, + ILocalizedEntityService localizedEntityService, + IPictureService pictureService, + IPriceCalculationService priceCalculationService, + ICurrencyService currencyService, + ITaxService taxService, + IPriceFormatter priceFormatter, + ICategoryService categoryService, + IProductAttributeParser productAttributeParser, + IProductService productService, + IDateTimeHelper dateTimeHelper, + MediaSettings mediaSettings) + { + _services = services; + _urlRecordService = urlRecordService; + _localizedEntityService = localizedEntityService; + _pictureService = pictureService; + _priceCalculationService = priceCalculationService; + _currencyService = currencyService; + _taxService = taxService; + _priceFormatter = priceFormatter; + _categoryService = categoryService; + _productAttributeParser = productAttributeParser; + _productService = productService; + _dateTimeHelper = dateTimeHelper; + + _mediaSettings = mediaSettings; + } + + #region Utilities + + private void SetProgress(DataExportTaskContext ctx, int loadedRecords) + { + if (!ctx.IsPreview && ctx.TaskContext.ScheduleTask != null && loadedRecords > 0) + { + int totalRecords = ctx.RecordsPerStore.Sum(x => x.Value); + + if (ctx.Profile.Limit > 0 && totalRecords > ctx.Profile.Limit) + totalRecords = ctx.Profile.Limit; + + ctx.RecordCount = Math.Min(ctx.RecordCount + loadedRecords, totalRecords); + + var msg = ctx.ProgressInfo.FormatInvariant(ctx.RecordCount, totalRecords); + + ctx.TaskContext.SetProgress(ctx.RecordCount, totalRecords, msg, true); + } + } + + private void SetProgress(DataExportTaskContext ctx, string message) + { + if (!ctx.IsPreview && ctx.TaskContext.ScheduleTask != null && message.HasValue()) + { + ctx.TaskContext.SetProgress(null, message, true); + } + } + + #endregion + + #region Getting data + + private IQueryable GetProductQuery(DataExportTaskContext ctx, int skip, int take) + { + IQueryable query = null; + + if (ctx.QueryProducts == null) + { + var searchContext = new ProductSearchContext + { + OrderBy = ProductSortingEnum.CreatedOn, + ProductIds = ctx.EntityIdsSelected, + StoreId = (ctx.Profile.PerStore ? ctx.Store.Id : ctx.Filter.StoreId), + VisibleIndividuallyOnly = true, + PriceMin = ctx.Filter.PriceMinimum, + PriceMax = ctx.Filter.PriceMaximum, + IsPublished = ctx.Filter.IsPublished, + WithoutCategories = ctx.Filter.WithoutCategories, + WithoutManufacturers = ctx.Filter.WithoutManufacturers, + ManufacturerId = ctx.Filter.ManufacturerId ?? 0, + FeaturedProducts = ctx.Filter.FeaturedProducts, + ProductType = ctx.Filter.ProductType, + ProductTagId = ctx.Filter.ProductTagId ?? 0, + IdMin = ctx.Filter.IdMinimum ?? 0, + IdMax = ctx.Filter.IdMaximum ?? 0, + AvailabilityMinimum = ctx.Filter.AvailabilityMinimum, + AvailabilityMaximum = ctx.Filter.AvailabilityMaximum + }; + + if (!ctx.Filter.IsPublished.HasValue) + searchContext.ShowHidden = true; + + if (ctx.Filter.CategoryIds != null && ctx.Filter.CategoryIds.Length > 0) + searchContext.CategoryIds = ctx.Filter.CategoryIds.ToList(); + + if (ctx.Filter.CreatedFrom.HasValue) + searchContext.CreatedFromUtc = _dateTimeHelper.ConvertToUtcTime(ctx.Filter.CreatedFrom.Value, _dateTimeHelper.CurrentTimeZone); + + if (ctx.Filter.CreatedTo.HasValue) + searchContext.CreatedToUtc = _dateTimeHelper.ConvertToUtcTime(ctx.Filter.CreatedTo.Value, _dateTimeHelper.CurrentTimeZone); + + query = _productService.PrepareProductSearchQuery(searchContext); + + query = query.OrderByDescending(x => x.CreatedOnUtc); + } + else + { + query = ctx.QueryProducts; + } + + if (skip > 0) + query = query.Skip(skip); + + if (take != int.MaxValue) + query = query.Take(take); + + return query; + } + + private List GetProducts(DataExportTaskContext ctx, int skip) + { + var result = new List(); + + var products = GetProductQuery(ctx, skip, PageSize).ToList(); + + foreach (var product in products) + { + if (product.ProductType == ProductType.SimpleProduct || product.ProductType == ProductType.BundledProduct) + { + result.Add(product); + } + else if (product.ProductType == ProductType.GroupedProduct) + { + if (ctx.Projection.NoGroupedProducts && !ctx.IsPreview) + { + var associatedSearchContext = new ProductSearchContext + { + OrderBy = ProductSortingEnum.CreatedOn, + PageSize = int.MaxValue, + StoreId = (ctx.Profile.PerStore ? ctx.Store.Id : ctx.Filter.StoreId), + VisibleIndividuallyOnly = false, + ParentGroupedProductId = product.Id + }; + + foreach (var associatedProduct in _productService.SearchProducts(associatedSearchContext)) + { + result.Add(associatedProduct); + } + } + else + { + result.Add(product); + } + } + } + + try + { + SetProgress(ctx, products.Count); + + _services.DbContext.DetachEntities(result); + } + catch { } + + return result; + } + + #endregion + + /// + /// The name of the public export folder + /// + public static string PublicFolder + { + get { return "Exchange"; } + } + + public static int PageSize + { + get { return 100; } + } + + public DataExportResult Export(DataExportRequest request, CancellationToken cancellationToken) + { + return null; + } + + public IList Preview(DataExportRequest request) + { + return null; + } + + public long GetDataCount(DataExportRequest request) + { + return 0; + } + } +} diff --git a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExportTaskToDynamic.cs b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporterToDynamic.cs similarity index 99% rename from src/Libraries/SmartStore.Services/DataExchange/Internal/DataExportTaskToDynamic.cs rename to src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporterToDynamic.cs index 4b4e4d2f07..a8be741ada 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExportTaskToDynamic.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporterToDynamic.cs @@ -26,7 +26,7 @@ namespace SmartStore.Services.DataExchange.Internal { - internal partial class DataExportTask + internal partial class DataExporter { private void PrepareProductDescription(DataExportTaskContext ctx, dynamic dynObject, Product product) { diff --git a/src/Libraries/SmartStore.Services/SmartStore.Services.csproj b/src/Libraries/SmartStore.Services/SmartStore.Services.csproj index c45f341aa4..dd2d310de4 100644 --- a/src/Libraries/SmartStore.Services/SmartStore.Services.csproj +++ b/src/Libraries/SmartStore.Services/SmartStore.Services.csproj @@ -168,7 +168,8 @@ - + + From e1d71419d702973a468ce7f20266e497fd4c0506 Mon Sep 17 00:00:00 2001 From: Murat Cakir Date: Tue, 10 Nov 2015 20:25:12 +0100 Subject: [PATCH 012/626] Removed obsolete EnumExtensions helper class --- .../Extensions/EnumExtensions.cs | 83 ------------------- .../SmartStore.Core/SmartStore.Core.csproj | 1 - .../Localization/LocalizationService.cs | 4 +- 3 files changed, 2 insertions(+), 86 deletions(-) delete mode 100644 src/Libraries/SmartStore.Core/Extensions/EnumExtensions.cs diff --git a/src/Libraries/SmartStore.Core/Extensions/EnumExtensions.cs b/src/Libraries/SmartStore.Core/Extensions/EnumExtensions.cs deleted file mode 100644 index bd96a8e069..0000000000 --- a/src/Libraries/SmartStore.Core/Extensions/EnumExtensions.cs +++ /dev/null @@ -1,83 +0,0 @@ -using System; -using System.Linq; -using System.Reflection; - -namespace SmartStore -{ - - public static class EnumExtensions - { - - /// - /// Checks if the specified enum flag is set on a flagged enumeration type. - /// - /// - /// - /// - /// - public static bool IsSet(this T value, T flags) where T : struct - { - Type type = typeof(T); - - // only works with enums - if (!type.IsEnum) - throw Error.Argument("T", "The type parameter T must be an enum type."); - - // handle each underlying type - Type numberType = Enum.GetUnderlyingType(type); - - if (numberType.Equals(typeof(int))) - { - return BoxUnbox(value, flags, (a, b) => (a & b) == b); - } - else if (numberType.Equals(typeof(sbyte))) - { - return BoxUnbox(value, flags, (a, b) => (a & b) == b); - } - else if (numberType.Equals(typeof(byte))) - { - return BoxUnbox(value, flags, (a, b) => (a & b) == b); - } - else if (numberType.Equals(typeof(short))) - { - return BoxUnbox(value, flags, (a, b) => (a & b) == b); - } - else if (numberType.Equals(typeof(ushort))) - { - return BoxUnbox(value, flags, (a, b) => (a & b) == b); - } - else if (numberType.Equals(typeof(uint))) - { - return BoxUnbox(value, flags, (a, b) => (a & b) == b); - } - else if (numberType.Equals(typeof(long))) - { - return BoxUnbox(value, flags, (a, b) => (a & b) == b); - } - else if (numberType.Equals(typeof(ulong))) - { - return BoxUnbox(value, flags, (a, b) => (a & b) == b); - } - else if (numberType.Equals(typeof(char))) - { - return BoxUnbox(value, flags, (a, b) => (a & b) == b); - } - else - { - throw new ArgumentException("Unknown enum underlying type " + - numberType.Name + "."); - } - } - - /// - /// Helper function for handling the value types. Boxes the params to - /// object so that the cast can be called on them. - /// - private static bool BoxUnbox(object value, object flags, Func op) - { - return op((T)value, (T)flags); - } - - } - -} diff --git a/src/Libraries/SmartStore.Core/SmartStore.Core.csproj b/src/Libraries/SmartStore.Core/SmartStore.Core.csproj index 5682e36739..d0d8ec245d 100644 --- a/src/Libraries/SmartStore.Core/SmartStore.Core.csproj +++ b/src/Libraries/SmartStore.Core/SmartStore.Core.csproj @@ -343,7 +343,6 @@ - diff --git a/src/Libraries/SmartStore.Services/Localization/LocalizationService.cs b/src/Libraries/SmartStore.Services/Localization/LocalizationService.cs index 07a55686b7..70a6058f65 100644 --- a/src/Libraries/SmartStore.Services/Localization/LocalizationService.cs +++ b/src/Libraries/SmartStore.Services/Localization/LocalizationService.cs @@ -461,7 +461,7 @@ public virtual void ImportResourcesFromXml( var resource = language.LocaleStringResources.Where(x => x.ResourceName.Equals(name, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault(); if (resource != null) { - if (mode.IsSet(ImportModeFlags.Update)) + if (mode.HasFlag(ImportModeFlags.Update)) { if (updateTouchedResources || !resource.IsTouched.GetValueOrDefault()) { @@ -473,7 +473,7 @@ public virtual void ImportResourcesFromXml( } else { - if (mode.IsSet(ImportModeFlags.Insert)) + if (mode.HasFlag(ImportModeFlags.Insert)) { toAdd.Add( new LocaleStringResource() From 75b8446877d0b9ac627705aedd2b219778f59d57 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Tue, 10 Nov 2015 22:13:02 +0100 Subject: [PATCH 013/626] Minor changes --- .../Domain/DataExchange/ExportEnums.cs | 6 +++--- .../Plugins/Providers/ProviderMetadata.cs | 2 +- .../DataExchange/ExportFeaturesAttribute.cs | 2 +- .../DataExchange/ExportProfileService.cs | 4 ++-- .../DataExchange/ExportProviderBase.cs | 5 ++++- .../ExportTask/ExportProfileTask.cs | 18 ++++++++--------- .../DataExchange/Internal/DataExportTask.cs | 2 +- .../Internal/DataExportTaskContext.cs | 2 +- .../DataExchange/Internal/DataExporter.cs | 2 +- ...terToDynamic.cs => DynamicEntityHelper.cs} | 20 +++++++++---------- .../Providers/CategoryXmlExportProvider.cs | 2 +- .../Providers/CustomerXlsxExportProvider.cs | 2 +- .../Providers/CustomerXmlExportProvider.cs | 2 +- .../ManufacturerXmlExportProvider.cs | 2 +- .../Providers/OrderXlsxExportProvider.cs | 2 +- .../Providers/OrderXmlExportProvider.cs | 2 +- .../Providers/ProductXlsxExportProvider.cs | 2 +- .../Providers/ProductXmlExportProvider.cs | 2 +- .../Providers/SubscriberCsvExportProvider.cs | 2 +- .../SmartStore.Services.csproj | 2 +- .../Providers/GmcXmlExportProvider.cs | 18 ++++++++--------- .../DependencyRegistrar.cs | 4 ++-- .../Models/DataExchange/ExportProfileModel.cs | 2 +- .../Customer/RegisterValidatorTests.cs | 1 + 24 files changed, 56 insertions(+), 52 deletions(-) rename src/Libraries/SmartStore.Services/DataExchange/Internal/{DataExporterToDynamic.cs => DynamicEntityHelper.cs} (98%) diff --git a/src/Libraries/SmartStore.Core/Domain/DataExchange/ExportEnums.cs b/src/Libraries/SmartStore.Core/Domain/DataExchange/ExportEnums.cs index 90cb107353..d1f6e2c8bd 100644 --- a/src/Libraries/SmartStore.Core/Domain/DataExchange/ExportEnums.cs +++ b/src/Libraries/SmartStore.Core/Domain/DataExchange/ExportEnums.cs @@ -1,5 +1,5 @@ - -using System; +using System; + namespace SmartStore.Core.Domain.DataExchange { /// @@ -63,7 +63,7 @@ public enum ExportAttributeValueMerging /// Controls data processing and projection items supported by an export provider /// [Flags] - public enum ExportFeature + public enum ExportFeatures { None = 0, diff --git a/src/Libraries/SmartStore.Core/Plugins/Providers/ProviderMetadata.cs b/src/Libraries/SmartStore.Core/Plugins/Providers/ProviderMetadata.cs index 05ef601ecc..ea7d3e4f36 100644 --- a/src/Libraries/SmartStore.Core/Plugins/Providers/ProviderMetadata.cs +++ b/src/Libraries/SmartStore.Core/Plugins/Providers/ProviderMetadata.cs @@ -76,7 +76,7 @@ public class ProviderMetadata /// /// Gets or sets flags that reflects what features of export data processing is supported by a provider /// - public ExportFeature ExportFeature { get; set; } + public ExportFeatures ExportFeature { get; set; } /// /// Gets or sets an array of widget system names, which depend on the current provider diff --git a/src/Libraries/SmartStore.Services/DataExchange/ExportFeaturesAttribute.cs b/src/Libraries/SmartStore.Services/DataExchange/ExportFeaturesAttribute.cs index 7f803715f4..43543de25a 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/ExportFeaturesAttribute.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/ExportFeaturesAttribute.cs @@ -10,6 +10,6 @@ namespace SmartStore.Services.DataExchange [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)] public sealed class ExportFeaturesAttribute : Attribute { - public ExportFeature Features { get; set; } + public ExportFeatures Features { get; set; } } } diff --git a/src/Libraries/SmartStore.Services/DataExchange/ExportProfileService.cs b/src/Libraries/SmartStore.Services/DataExchange/ExportProfileService.cs index 465b97a3c2..6c5c7eb5d0 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/ExportProfileService.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/ExportProfileService.cs @@ -116,7 +116,7 @@ public virtual ExportProfile InsertExportProfile(Provider provi RemoveCriticalCharacters = true, CriticalCharacters = "¼,½,¾", PriceType = PriceDisplayType.PreSelectedPrice, - NoGroupedProducts = (provider.Metadata.ExportFeature.HasFlag(ExportFeature.CanOmitGroupedProducts) ? true : false) + NoGroupedProducts = (provider.Metadata.ExportFeature.HasFlag(ExportFeatures.CanOmitGroupedProducts) ? true : false) }; var filter = new ExportFilter @@ -150,7 +150,7 @@ public virtual ExportProfile InsertExportProfile(Provider provi { if (cloneProfile == null) { - if (provider.Metadata.ExportFeature.HasFlag(ExportFeature.CreatesInitialPublicDeployment)) + if (provider.Metadata.ExportFeature.HasFlag(ExportFeatures.CreatesInitialPublicDeployment)) { profile.Deployments.Add(new ExportDeployment { diff --git a/src/Libraries/SmartStore.Services/DataExchange/ExportProviderBase.cs b/src/Libraries/SmartStore.Services/DataExchange/ExportProviderBase.cs index f0dd39a95e..aec8f4434a 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/ExportProviderBase.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/ExportProviderBase.cs @@ -32,8 +32,11 @@ public virtual ExportConfigurationInfo ConfigurationInfo /// Export data to a file /// /// Export execution context - public virtual void Execute(IExportExecuteContext context) + protected abstract void Export(IExportExecuteContext context); + + public void Execute(IExportExecuteContext context) { + Export(context); } /// diff --git a/src/Libraries/SmartStore.Services/DataExchange/ExportTask/ExportProfileTask.cs b/src/Libraries/SmartStore.Services/DataExchange/ExportTask/ExportProfileTask.cs index 0064cf709e..3bc601bedf 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/ExportTask/ExportProfileTask.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/ExportTask/ExportProfileTask.cs @@ -1540,7 +1540,7 @@ private List ConvertToExpando(DataExportTaskContext ctx, Product produc var productTemplate = ctx.ProductTemplates.FirstOrDefault(x => x.Key == product.ProductTemplateId); var pictureSize = _mediaSettings.Value.ProductDetailsPictureSize; - if (ctx.Supports(ExportFeature.CanIncludeMainPicture) && ctx.Projection.PictureSize > 0) + if (ctx.Supports(ExportFeatures.CanIncludeMainPicture) && ctx.Projection.PictureSize > 0) pictureSize = ctx.Projection.PictureSize; var perfLoadId = (ctx.IsPreview ? 0 : product.Id); // perf preview (it's a compromise) @@ -1746,12 +1746,12 @@ private List ConvertToExpando(DataExportTaskContext ctx, Product produc #region more attribute controlled data - if (ctx.Supports(ExportFeature.CanProjectDescription)) + if (ctx.Supports(ExportFeatures.CanProjectDescription)) { PrepareProductDescription(ctx, expando, product); } - if (ctx.Supports(ExportFeature.OffersBrandFallback)) + if (ctx.Supports(ExportFeatures.OffersBrandFallback)) { string brand = null; var productManus = ctx.ProductExportContext.ProductManufacturers.Load(perfLoadId); @@ -1765,7 +1765,7 @@ private List ConvertToExpando(DataExportTaskContext ctx, Product produc expando._Brand = brand; } - if (ctx.Supports(ExportFeature.CanIncludeMainPicture)) + if (ctx.Supports(ExportFeatures.CanIncludeMainPicture)) { if (productPictures != null && productPictures.Any()) expando._MainPictureUrl = _pictureService.Value.GetPictureUrl(productPictures.First().Picture, ctx.Projection.PictureSize, storeLocation: ctx.Store.Url); @@ -1807,18 +1807,18 @@ private List ConvertToExpando(DataExportTaskContext ctx, Product produc // navigation properties GetDeliveryTimeAndQuantityUnit(ctx, exp, product.DeliveryTimeId, product.QuantityUnitId); - if (ctx.Supports(ExportFeature.UsesSkuAsMpnFallback) && product.ManufacturerPartNumber.IsEmpty()) + if (ctx.Supports(ExportFeatures.UsesSkuAsMpnFallback) && product.ManufacturerPartNumber.IsEmpty()) { exp.ManufacturerPartNumber = product.Sku; } - if (ctx.Supports(ExportFeature.OffersShippingTimeFallback)) + if (ctx.Supports(ExportFeatures.OffersShippingTimeFallback)) { dynamic deliveryTime = exp.DeliveryTime; exp._ShippingTime = (deliveryTime == null ? ctx.Projection.ShippingTime : deliveryTime.Name); } - if (ctx.Supports(ExportFeature.OffersShippingCostsFallback)) + if (ctx.Supports(ExportFeatures.OffersShippingCostsFallback)) { exp._FreeShippingThreshold = ctx.Projection.FreeShippingThreshold; @@ -1828,7 +1828,7 @@ private List ConvertToExpando(DataExportTaskContext ctx, Product produc exp._ShippingCosts = ctx.Projection.ShippingCosts; } - if (ctx.Supports(ExportFeature.UsesOldPrice)) + if (ctx.Supports(ExportFeatures.UsesOldPrice)) { if (product.OldPrice != decimal.Zero && product.OldPrice != (decimal)exp.Price && !(product.ProductType == ProductType.BundledProduct && product.BundlePerItemPricing)) { @@ -1848,7 +1848,7 @@ private List ConvertToExpando(DataExportTaskContext ctx, Product produc } } - if (ctx.Supports(ExportFeature.UsesSpecialPrice)) + if (ctx.Supports(ExportFeatures.UsesSpecialPrice)) { exp._SpecialPrice = null; exp._RegularPrice = null; // price if a special price would not exist diff --git a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExportTask.cs b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExportTask.cs index e151674022..ea3c676587 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExportTask.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExportTask.cs @@ -4,7 +4,7 @@ namespace SmartStore.Services.DataExchange.Internal { - internal partial class DataExportTask : ITask + public partial class DataExportTask : ITask { private readonly IDataExporter _exporter; private readonly IExportProfileService _exportProfileService; diff --git a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExportTaskContext.cs b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExportTaskContext.cs index 7929d6504b..9ed4dd818a 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExportTaskContext.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExportTaskContext.cs @@ -79,7 +79,7 @@ public bool IsPreview public ExportProfile Profile { get; private set; } public Provider Provider { get; private set; } - public bool Supports(ExportFeature feature) + public bool Supports(ExportFeatures feature) { return (!IsPreview && Provider.Metadata.ExportFeature.HasFlag(feature)); } diff --git a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporter.cs b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporter.cs index aa0a07f44f..c0c44e0304 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporter.cs @@ -19,7 +19,7 @@ namespace SmartStore.Services.DataExchange.Internal { - internal partial class DataExporter : IDataExporter + public partial class DataExporter : IDataExporter { private static readonly ReaderWriterLockSlim _rwLock = new ReaderWriterLockSlim(); diff --git a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporterToDynamic.cs b/src/Libraries/SmartStore.Services/DataExchange/Internal/DynamicEntityHelper.cs similarity index 98% rename from src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporterToDynamic.cs rename to src/Libraries/SmartStore.Services/DataExchange/Internal/DynamicEntityHelper.cs index a8be741ada..c1ebf6a7a5 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporterToDynamic.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Internal/DynamicEntityHelper.cs @@ -26,7 +26,7 @@ namespace SmartStore.Services.DataExchange.Internal { - internal partial class DataExporter + public partial class DataExporter { private void PrepareProductDescription(DataExportTaskContext ctx, dynamic dynObject, Product product) { @@ -184,18 +184,18 @@ private void MergeWithCombination(DataExportTaskContext ctx, dynamic dynObject, ToDeliveryTime(ctx, dynObject, product.DeliveryTimeId); ToQuantityUnit(ctx, dynObject, product.QuantityUnitId); - if (ctx.Supports(ExportFeature.UsesSkuAsMpnFallback) && product.ManufacturerPartNumber.IsEmpty()) + if (ctx.Supports(ExportFeatures.UsesSkuAsMpnFallback) && product.ManufacturerPartNumber.IsEmpty()) { dynObject.ManufacturerPartNumber = product.Sku; } - if (ctx.Supports(ExportFeature.OffersShippingTimeFallback)) + if (ctx.Supports(ExportFeatures.OffersShippingTimeFallback)) { dynamic deliveryTime = dynObject.DeliveryTime; dynObject._ShippingTime = (deliveryTime == null ? ctx.Projection.ShippingTime : deliveryTime.Name); } - if (ctx.Supports(ExportFeature.OffersShippingCostsFallback)) + if (ctx.Supports(ExportFeatures.OffersShippingCostsFallback)) { dynObject._FreeShippingThreshold = ctx.Projection.FreeShippingThreshold; @@ -205,7 +205,7 @@ private void MergeWithCombination(DataExportTaskContext ctx, dynamic dynObject, dynObject._ShippingCosts = ctx.Projection.ShippingCosts; } - if (ctx.Supports(ExportFeature.UsesOldPrice)) + if (ctx.Supports(ExportFeatures.UsesOldPrice)) { if (product.OldPrice != decimal.Zero && product.OldPrice != (decimal)dynObject.Price && !(product.ProductType == ProductType.BundledProduct && product.BundlePerItemPricing)) { @@ -225,7 +225,7 @@ private void MergeWithCombination(DataExportTaskContext ctx, dynamic dynObject, } } - if (ctx.Supports(ExportFeature.UsesSpecialPrice)) + if (ctx.Supports(ExportFeatures.UsesSpecialPrice)) { dynObject._SpecialPrice = null; dynObject._RegularPrice = null; // price if a special price would not exist @@ -738,7 +738,7 @@ private List Convert(DataExportTaskContext ctx, Product product) var productTemplate = ctx.ProductTemplates.FirstOrDefault(x => x.Key == product.ProductTemplateId); var pictureSize = _mediaSettings.ProductDetailsPictureSize; - if (ctx.Supports(ExportFeature.CanIncludeMainPicture) && ctx.Projection.PictureSize > 0) + if (ctx.Supports(ExportFeatures.CanIncludeMainPicture) && ctx.Projection.PictureSize > 0) pictureSize = ctx.Projection.PictureSize; var perfLoadId = (ctx.IsPreview ? 0 : product.Id); // perf preview (it's a compromise) @@ -912,12 +912,12 @@ private List Convert(DataExportTaskContext ctx, Product product) #region more attribute controlled data - if (ctx.Supports(ExportFeature.CanProjectDescription)) + if (ctx.Supports(ExportFeatures.CanProjectDescription)) { PrepareProductDescription(ctx, dynObject, product); } - if (ctx.Supports(ExportFeature.OffersBrandFallback)) + if (ctx.Supports(ExportFeatures.OffersBrandFallback)) { string brand = null; var productManus = ctx.ProductExportContext.ProductManufacturers.Load(perfLoadId); @@ -931,7 +931,7 @@ private List Convert(DataExportTaskContext ctx, Product product) dynObject._Brand = brand; } - if (ctx.Supports(ExportFeature.CanIncludeMainPicture)) + if (ctx.Supports(ExportFeatures.CanIncludeMainPicture)) { if (productPictures != null && productPictures.Any()) dynObject._MainPictureUrl = _pictureService.GetPictureUrl(productPictures.First().Picture, ctx.Projection.PictureSize, storeLocation: ctx.Store.Url); diff --git a/src/Libraries/SmartStore.Services/DataExchange/Providers/CategoryXmlExportProvider.cs b/src/Libraries/SmartStore.Services/DataExchange/Providers/CategoryXmlExportProvider.cs index 0a9c08f69e..401b9a165c 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Providers/CategoryXmlExportProvider.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Providers/CategoryXmlExportProvider.cs @@ -29,7 +29,7 @@ public override string FileExtension get { return "XML"; } } - public override void Execute(IExportExecuteContext context) + protected override void Export(IExportExecuteContext context) { using (var helper = new ExportXmlHelper(context.DataStream)) { diff --git a/src/Libraries/SmartStore.Services/DataExchange/Providers/CustomerXlsxExportProvider.cs b/src/Libraries/SmartStore.Services/DataExchange/Providers/CustomerXlsxExportProvider.cs index f0eba13df9..133ea6e3a7 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Providers/CustomerXlsxExportProvider.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Providers/CustomerXlsxExportProvider.cs @@ -105,7 +105,7 @@ public override string FileExtension get { return "XLSX"; } } - public override void Execute(IExportExecuteContext context) + protected override void Export(IExportExecuteContext context) { var invariantCulture = CultureInfo.InvariantCulture; diff --git a/src/Libraries/SmartStore.Services/DataExchange/Providers/CustomerXmlExportProvider.cs b/src/Libraries/SmartStore.Services/DataExchange/Providers/CustomerXmlExportProvider.cs index 4963380787..7b7611fb2a 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Providers/CustomerXmlExportProvider.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Providers/CustomerXmlExportProvider.cs @@ -28,7 +28,7 @@ public override string FileExtension get { return "XML"; } } - public override void Execute(IExportExecuteContext context) + protected override void Export(IExportExecuteContext context) { using (var helper = new ExportXmlHelper(context.DataStream)) { diff --git a/src/Libraries/SmartStore.Services/DataExchange/Providers/ManufacturerXmlExportProvider.cs b/src/Libraries/SmartStore.Services/DataExchange/Providers/ManufacturerXmlExportProvider.cs index 341f1a8da1..74eb5551a7 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Providers/ManufacturerXmlExportProvider.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Providers/ManufacturerXmlExportProvider.cs @@ -29,7 +29,7 @@ public override string FileExtension get { return "XML"; } } - public override void Execute(IExportExecuteContext context) + protected override void Export(IExportExecuteContext context) { using (var helper = new ExportXmlHelper(context.DataStream)) { diff --git a/src/Libraries/SmartStore.Services/DataExchange/Providers/OrderXlsxExportProvider.cs b/src/Libraries/SmartStore.Services/DataExchange/Providers/OrderXlsxExportProvider.cs index 31579dd1c5..b36b4286d9 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Providers/OrderXlsxExportProvider.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Providers/OrderXlsxExportProvider.cs @@ -105,7 +105,7 @@ public override string FileExtension get { return "XLSX"; } } - public override void Execute(IExportExecuteContext context) + protected override void Export(IExportExecuteContext context) { using (var xlPackage = new ExcelPackage(context.DataStream)) { diff --git a/src/Libraries/SmartStore.Services/DataExchange/Providers/OrderXmlExportProvider.cs b/src/Libraries/SmartStore.Services/DataExchange/Providers/OrderXmlExportProvider.cs index 9a9ebd03a0..6a878ddb84 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Providers/OrderXmlExportProvider.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Providers/OrderXmlExportProvider.cs @@ -32,7 +32,7 @@ public override string FileExtension get { return "XML"; } } - public override void Execute(IExportExecuteContext context) + protected override void Export(IExportExecuteContext context) { var invariantCulture = CultureInfo.InvariantCulture; diff --git a/src/Libraries/SmartStore.Services/DataExchange/Providers/ProductXlsxExportProvider.cs b/src/Libraries/SmartStore.Services/DataExchange/Providers/ProductXlsxExportProvider.cs index 3b9c89d753..e908fa8001 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Providers/ProductXlsxExportProvider.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Providers/ProductXlsxExportProvider.cs @@ -173,7 +173,7 @@ public override string FileExtension get { return "XLSX"; } } - public override void Execute(IExportExecuteContext context) + protected override void Export(IExportExecuteContext context) { using (var xlPackage = new ExcelPackage(context.DataStream)) { diff --git a/src/Libraries/SmartStore.Services/DataExchange/Providers/ProductXmlExportProvider.cs b/src/Libraries/SmartStore.Services/DataExchange/Providers/ProductXmlExportProvider.cs index 63d5dc4122..4c2f86ccfd 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Providers/ProductXmlExportProvider.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Providers/ProductXmlExportProvider.cs @@ -28,7 +28,7 @@ public override string FileExtension get { return "XML"; } } - public override void Execute(IExportExecuteContext context) + protected override void Export(IExportExecuteContext context) { using (var helper = new ExportXmlHelper(context.DataStream)) { diff --git a/src/Libraries/SmartStore.Services/DataExchange/Providers/SubscriberCsvExportProvider.cs b/src/Libraries/SmartStore.Services/DataExchange/Providers/SubscriberCsvExportProvider.cs index 959ae0ee5d..bf8b192421 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Providers/SubscriberCsvExportProvider.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Providers/SubscriberCsvExportProvider.cs @@ -30,7 +30,7 @@ public override string FileExtension get { return "CSV"; } } - public override void Execute(IExportExecuteContext context) + protected override void Export(IExportExecuteContext context) { using (var writer = new StreamWriter(context.DataStream, Encoding.UTF8, 1024, true)) { diff --git a/src/Libraries/SmartStore.Services/SmartStore.Services.csproj b/src/Libraries/SmartStore.Services/SmartStore.Services.csproj index dd2d310de4..0e67aca232 100644 --- a/src/Libraries/SmartStore.Services/SmartStore.Services.csproj +++ b/src/Libraries/SmartStore.Services/SmartStore.Services.csproj @@ -169,7 +169,7 @@ - + diff --git a/src/Plugins/SmartStore.GoogleMerchantCenter/Providers/GmcXmlExportProvider.cs b/src/Plugins/SmartStore.GoogleMerchantCenter/Providers/GmcXmlExportProvider.cs index 21472367d2..5671091d54 100644 --- a/src/Plugins/SmartStore.GoogleMerchantCenter/Providers/GmcXmlExportProvider.cs +++ b/src/Plugins/SmartStore.GoogleMerchantCenter/Providers/GmcXmlExportProvider.cs @@ -18,14 +18,14 @@ namespace SmartStore.GoogleMerchantCenter.Providers [FriendlyName("Google Merchant Center XML product feed")] [DisplayOrder(1)] [ExportFeatures(Features = - ExportFeature.CreatesInitialPublicDeployment | - ExportFeature.CanOmitGroupedProducts | - ExportFeature.CanProjectAttributeCombinations | - ExportFeature.CanProjectDescription | - ExportFeature.UsesSkuAsMpnFallback | - ExportFeature.OffersBrandFallback | - ExportFeature.CanIncludeMainPicture | - ExportFeature.UsesSpecialPrice)] + ExportFeatures.CreatesInitialPublicDeployment | + ExportFeatures.CanOmitGroupedProducts | + ExportFeatures.CanProjectAttributeCombinations | + ExportFeatures.CanProjectDescription | + ExportFeatures.UsesSkuAsMpnFallback | + ExportFeatures.OffersBrandFallback | + ExportFeatures.CanIncludeMainPicture | + ExportFeatures.UsesSpecialPrice)] public class GmcXmlExportProvider : ExportProviderBase { private const string _googleNamespace = "http://base.google.com/ns/1.0"; @@ -153,7 +153,7 @@ public override string FileExtension get { return "XML"; } } - public override void Execute(IExportExecuteContext context) + protected override void Export(IExportExecuteContext context) { dynamic currency = context.Currency; string measureWeightSystemKey = ""; diff --git a/src/Presentation/SmartStore.Web.Framework/DependencyRegistrar.cs b/src/Presentation/SmartStore.Web.Framework/DependencyRegistrar.cs index 1e43a6ec12..5da257cb6d 100644 --- a/src/Presentation/SmartStore.Web.Framework/DependencyRegistrar.cs +++ b/src/Presentation/SmartStore.Web.Framework/DependencyRegistrar.cs @@ -867,7 +867,7 @@ private bool GetIsHidden(Type type) return false; } - private ExportFeature GetExportFeature(Type type) + private ExportFeatures GetExportFeature(Type type) { var attr = type.GetAttribute(false); @@ -876,7 +876,7 @@ private ExportFeature GetExportFeature(Type type) return attr.Features; } - return ExportFeature.None; + return ExportFeatures.None; } private Tuple GetFriendlyName(Type type, PluginDescriptor descriptor) diff --git a/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ExportProfileModel.cs b/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ExportProfileModel.cs index a863d55d3f..493636f238 100644 --- a/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ExportProfileModel.cs +++ b/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ExportProfileModel.cs @@ -95,7 +95,7 @@ public class ProviderModel public Type ConfigDataType { get; set; } public object ConfigData { get; set; } - public ExportFeature Feature { get; set; } + public ExportFeatures Feature { get; set; } [SmartResourceDisplayName("Common.Image")] public string ThumbnailUrl { get; set; } diff --git a/src/Tests/SmartStore.Web.MVC.Tests/Public/Validators/Customer/RegisterValidatorTests.cs b/src/Tests/SmartStore.Web.MVC.Tests/Public/Validators/Customer/RegisterValidatorTests.cs index 8998a635ef..a508e02b51 100644 --- a/src/Tests/SmartStore.Web.MVC.Tests/Public/Validators/Customer/RegisterValidatorTests.cs +++ b/src/Tests/SmartStore.Web.MVC.Tests/Public/Validators/Customer/RegisterValidatorTests.cs @@ -18,6 +18,7 @@ public class RegisterValidatorTests : BaseValidatorTests public new void Setup() { _customerSettings = new CustomerSettings(); + _taxSettings = new TaxSettings(); _validator = new RegisterValidator(_localizationService, _customerSettings, _taxSettings); } From 23d86056e7413508ff2b633378359d459be10263 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Tue, 10 Nov 2015 22:16:34 +0100 Subject: [PATCH 014/626] More minor changes --- .../Plugins/Providers/ProviderMetadata.cs | 2 +- .../DataExchange/ExportProfileService.cs | 4 ++-- .../DataExchange/Internal/DataExportTaskContext.cs | 2 +- .../DependencyRegistrar.cs | 2 +- .../Administration/Controllers/ExportController.cs | 2 +- .../Views/Export/_Tab.Projection.cshtml | 14 +++++++------- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/Libraries/SmartStore.Core/Plugins/Providers/ProviderMetadata.cs b/src/Libraries/SmartStore.Core/Plugins/Providers/ProviderMetadata.cs index ea7d3e4f36..d07a628170 100644 --- a/src/Libraries/SmartStore.Core/Plugins/Providers/ProviderMetadata.cs +++ b/src/Libraries/SmartStore.Core/Plugins/Providers/ProviderMetadata.cs @@ -76,7 +76,7 @@ public class ProviderMetadata /// /// Gets or sets flags that reflects what features of export data processing is supported by a provider /// - public ExportFeatures ExportFeature { get; set; } + public ExportFeatures ExportFeatures { get; set; } /// /// Gets or sets an array of widget system names, which depend on the current provider diff --git a/src/Libraries/SmartStore.Services/DataExchange/ExportProfileService.cs b/src/Libraries/SmartStore.Services/DataExchange/ExportProfileService.cs index 6c5c7eb5d0..1651171aa2 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/ExportProfileService.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/ExportProfileService.cs @@ -116,7 +116,7 @@ public virtual ExportProfile InsertExportProfile(Provider provi RemoveCriticalCharacters = true, CriticalCharacters = "¼,½,¾", PriceType = PriceDisplayType.PreSelectedPrice, - NoGroupedProducts = (provider.Metadata.ExportFeature.HasFlag(ExportFeatures.CanOmitGroupedProducts) ? true : false) + NoGroupedProducts = (provider.Metadata.ExportFeatures.HasFlag(ExportFeatures.CanOmitGroupedProducts) ? true : false) }; var filter = new ExportFilter @@ -150,7 +150,7 @@ public virtual ExportProfile InsertExportProfile(Provider provi { if (cloneProfile == null) { - if (provider.Metadata.ExportFeature.HasFlag(ExportFeatures.CreatesInitialPublicDeployment)) + if (provider.Metadata.ExportFeatures.HasFlag(ExportFeatures.CreatesInitialPublicDeployment)) { profile.Deployments.Add(new ExportDeployment { diff --git a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExportTaskContext.cs b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExportTaskContext.cs index 9ed4dd818a..dff4f49b7d 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExportTaskContext.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExportTaskContext.cs @@ -81,7 +81,7 @@ public bool IsPreview public bool Supports(ExportFeatures feature) { - return (!IsPreview && Provider.Metadata.ExportFeature.HasFlag(feature)); + return (!IsPreview && Provider.Metadata.ExportFeatures.HasFlag(feature)); } public ExportFilter Filter { get; private set; } diff --git a/src/Presentation/SmartStore.Web.Framework/DependencyRegistrar.cs b/src/Presentation/SmartStore.Web.Framework/DependencyRegistrar.cs index 5da257cb6d..7eea57921e 100644 --- a/src/Presentation/SmartStore.Web.Framework/DependencyRegistrar.cs +++ b/src/Presentation/SmartStore.Web.Framework/DependencyRegistrar.cs @@ -789,7 +789,7 @@ protected override void Load(ContainerBuilder builder) m.For(em => em.IsConfigurable, isConfigurable); m.For(em => em.IsEditable, isEditable); m.For(em => em.IsHidden, isHidden); - m.For(em => em.ExportFeature, exportFeature); + m.For(em => em.ExportFeatures, exportFeature); }); // register specific provider type diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs index 3b8f1306d7..e53c712192 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs @@ -280,7 +280,7 @@ private void PrepareProfileModelForEdit(ExportProfileModel model, ExportProfile if (provider != null) { - model.Provider.Feature = provider.Metadata.ExportFeature; + model.Provider.Feature = provider.Metadata.ExportFeatures; if (model.Provider.EntityType == ExportEntityType.Product) { diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Export/_Tab.Projection.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Export/_Tab.Projection.cshtml index 3d02c0a230..02337cf8b9 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Export/_Tab.Projection.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Export/_Tab.Projection.cshtml @@ -42,7 +42,7 @@ @if (Model.Provider.EntityType == ExportEntityType.Product) { - if (Model.Provider.Feature.HasFlag(ExportFeature.CanProjectAttributeCombinations)) + if (Model.Provider.Feature.HasFlag(ExportFeatures.CanProjectAttributeCombinations)) { @@ -71,7 +71,7 @@ } - if (Model.Provider.Feature.HasFlag(ExportFeature.CanOmitGroupedProducts)) + if (Model.Provider.Feature.HasFlag(ExportFeatures.CanOmitGroupedProducts)) { @@ -110,7 +110,7 @@ - if (Model.Provider.Feature.HasFlag(ExportFeature.OffersShippingTimeFallback)) + if (Model.Provider.Feature.HasFlag(ExportFeatures.OffersShippingTimeFallback)) { @@ -123,7 +123,7 @@ } - if (Model.Provider.Feature.HasFlag(ExportFeature.OffersShippingCostsFallback)) + if (Model.Provider.Feature.HasFlag(ExportFeatures.OffersShippingCostsFallback)) { @@ -145,7 +145,7 @@ } - if (Model.Provider.Feature.HasFlag(ExportFeature.CanIncludeMainPicture)) + if (Model.Provider.Feature.HasFlag(ExportFeatures.CanIncludeMainPicture)) { @@ -158,7 +158,7 @@ } - if (Model.Provider.Feature.HasFlag(ExportFeature.OffersBrandFallback)) + if (Model.Provider.Feature.HasFlag(ExportFeatures.OffersBrandFallback)) { @@ -171,7 +171,7 @@ } - if (Model.Provider.Feature.HasFlag(ExportFeature.CanProjectDescription)) + if (Model.Provider.Feature.HasFlag(ExportFeatures.CanProjectDescription)) { From c951a1d29ae8f9521365078a6b98dd073dbc0f86 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Wed, 11 Nov 2015 12:55:53 +0100 Subject: [PATCH 015/626] Further IDataExporter implementation --- .../DataExchange/IDataExporter.cs | 29 +- .../DataExchange/Internal/DataExportTask.cs | 12 +- .../DataExchange/Internal/DataExporter.cs | 917 +++++++++++++++++- .../Internal/DataExporterContext.cs | 218 +++++ .../Internal/DynamicEntityHelper.cs | 130 +-- .../SmartStore.Services.csproj | 1 + 6 files changed, 1191 insertions(+), 116 deletions(-) create mode 100644 src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporterContext.cs diff --git a/src/Libraries/SmartStore.Services/DataExchange/IDataExporter.cs b/src/Libraries/SmartStore.Services/DataExchange/IDataExporter.cs index 82820238d8..4a96e5c515 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/IDataExporter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/IDataExporter.cs @@ -6,7 +6,8 @@ namespace SmartStore.Services.DataExchange { - public delegate void ProgressSetter(int value, int maximum, string message); + public delegate void ProgressValueSetter(int value, int maximum, string message); + public delegate void ProgressMessageSetter(string message); public interface IDataExporter { @@ -23,24 +24,31 @@ public interface IDataExporter public class DataExportRequest { - private readonly static ProgressSetter _voidProgressSetter = DataExportRequest.SetProgress; + private readonly static ProgressValueSetter _voidProgressValueSetter = DataExportRequest.SetProgress; + private readonly static ProgressMessageSetter _voidProgressMessageSetter = DataExportRequest.SetProgress; - public DataExportRequest(ExportProfile profile) + public DataExportRequest(ExportProfile profile, Provider provider) { Guard.ArgumentNotNull(() => profile); + Guard.ArgumentNotNull(() => provider); - CustomData = new Dictionary(StringComparer.OrdinalIgnoreCase); - ProgressSetter = _voidProgressSetter; Profile = profile; - } + Provider = provider; + + ProgressValueSetter = _voidProgressValueSetter; + ProgressMessageSetter = _voidProgressMessageSetter; + + CustomData = new Dictionary(StringComparer.OrdinalIgnoreCase); + } public ExportProfile Profile { get; private set; } - public Provider Provider { get; set; } + public Provider Provider { get; private set; } public IEnumerable EntitiesToExport { get; set; } - public ProgressSetter ProgressSetter { get; set; } + public ProgressValueSetter ProgressValueSetter { get; set; } + public ProgressMessageSetter ProgressMessageSetter { get; set; } public IDictionary CustomData { get; private set; } @@ -49,5 +57,10 @@ private static void SetProgress(int val, int max, string msg) { // do nothing } + + private static void SetProgress(string msg) + { + // do nothing + } } } diff --git a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExportTask.cs b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExportTask.cs index ea3c676587..b1e3d31f54 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExportTask.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExportTask.cs @@ -37,10 +37,16 @@ public void Execute(TaskExecutionContext ctx) throw new SmartException(T("Admin.Common.ProviderNotLoaded", profile.ProviderSystemName.NaIfEmpty())); // build export request - var request = new DataExportRequest(profile); - request.ProgressSetter = delegate(int val, int max, string msg) + var request = new DataExportRequest(profile, provider); + + request.ProgressValueSetter = delegate(int val, int max, string msg) + { + ctx.SetProgress(val, max, msg, true); + }; + + request.ProgressMessageSetter = delegate(string msg) { - ctx.SetProgress(val, max, msg); + ctx.SetProgress(null, msg, true); }; if (selectedEntityIds.HasValue()) diff --git a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporter.cs b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporter.cs index c0c44e0304..391b210db6 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporter.cs @@ -1,21 +1,38 @@ using System; using System.Collections.Generic; +using System.IO; +using System.IO.Compression; using System.Linq; +using System.Text; using System.Threading; using System.Web; +using SmartStore.Core; +using SmartStore.Core.Data; using SmartStore.Core.Domain.Catalog; +using SmartStore.Core.Domain.Customers; using SmartStore.Core.Domain.DataExchange; using SmartStore.Core.Domain.Media; using SmartStore.Core.Domain.Messages; +using SmartStore.Core.Domain.Orders; +using SmartStore.Core.Domain.Stores; +using SmartStore.Core.Email; using SmartStore.Core.Localization; +using SmartStore.Core.Logging; using SmartStore.Services.Catalog; +using SmartStore.Services.Common; +using SmartStore.Services.Customers; using SmartStore.Services.Directory; using SmartStore.Services.Helpers; using SmartStore.Services.Localization; using SmartStore.Services.Media; +using SmartStore.Services.Messages; +using SmartStore.Services.Orders; using SmartStore.Services.Seo; +using SmartStore.Services.Shipping; using SmartStore.Services.Tasks; using SmartStore.Services.Tax; +using SmartStore.Utilities; +using SmartStore.Utilities.Threading; namespace SmartStore.Services.DataExchange.Internal { @@ -23,57 +40,121 @@ public partial class DataExporter : IDataExporter { private static readonly ReaderWriterLockSlim _rwLock = new ReaderWriterLockSlim(); + #region Dependencies + private readonly ICommonServices _services; - private readonly IUrlRecordService _urlRecordService; - private readonly ILocalizedEntityService _localizedEntityService; - private readonly IPictureService _pictureService; - private readonly IPriceCalculationService _priceCalculationService; - private readonly ICurrencyService _currencyService; - private readonly ITaxService _taxService; - private readonly IPriceFormatter _priceFormatter; - private readonly ICategoryService _categoryService; - private readonly IProductAttributeParser _productAttributeParser; - private readonly IProductService _productService; - private readonly IDateTimeHelper _dateTimeHelper; - - private MediaSettings _mediaSettings; + private readonly Lazy _priceFormatter; + private readonly Lazy _dateTimeHelper; + private readonly Lazy _exportProfileService; + private readonly Lazy _localizedEntityService; + private readonly Lazy _languageService; + private readonly Lazy _urlRecordService; + private readonly Lazy _pictureService; + private readonly Lazy _priceCalculationService; + private readonly Lazy _currencyService; + private readonly Lazy _taxService; + private readonly Lazy _categoryService; + private readonly Lazy _productAttributeParser; + private readonly Lazy _productAttributeService; + private readonly Lazy _productTemplateService; + private readonly Lazy _productService; + private readonly Lazy _orderService; + private readonly Lazy _manufacturerService; + private readonly Lazy _customerService; + private readonly Lazy _addressService; + private readonly Lazy _countryService; + private readonly Lazy _shipmentService; + private readonly Lazy _genericAttributeService; + private readonly Lazy _emailAccountService; + private readonly Lazy _emailSender; + private readonly Lazy _deliveryTimeService; + private readonly Lazy _quantityUnitService; + + private readonly Lazy>_customerRepository; + private readonly Lazy> _subscriptionRepository; + + private Lazy _dataExchangeSettings; + private Lazy _mediaSettings; public DataExporter( ICommonServices services, - IUrlRecordService urlRecordService, - ILocalizedEntityService localizedEntityService, - IPictureService pictureService, - IPriceCalculationService priceCalculationService, - ICurrencyService currencyService, - ITaxService taxService, - IPriceFormatter priceFormatter, - ICategoryService categoryService, - IProductAttributeParser productAttributeParser, - IProductService productService, - IDateTimeHelper dateTimeHelper, - MediaSettings mediaSettings) + Lazy priceFormatter, + Lazy dateTimeHelper, + Lazy exportProfileService, + Lazy localizedEntityService, + Lazy languageService, + Lazy urlRecordService, + Lazy pictureService, + Lazy priceCalculationService, + Lazy currencyService, + Lazy taxService, + Lazy categoryService, + Lazy productAttributeParser, + Lazy productAttributeService, + Lazy productTemplateService, + Lazy productService, + Lazy orderService, + Lazy manufacturerService, + Lazy customerService, + Lazy addressService, + Lazy countryService, + Lazy shipmentService, + Lazy genericAttributeService, + Lazy emailAccountService, + Lazy emailSender, + Lazy deliveryTimeService, + Lazy quantityUnitService, + Lazy> customerRepository, + Lazy> subscriptionRepository, + Lazy dataExchangeSettings, + Lazy mediaSettings) { + _priceFormatter = priceFormatter; + _dateTimeHelper = dateTimeHelper; _services = services; - _urlRecordService = urlRecordService; + _exportProfileService = exportProfileService; _localizedEntityService = localizedEntityService; + _languageService = languageService; + _urlRecordService = urlRecordService; _pictureService = pictureService; _priceCalculationService = priceCalculationService; _currencyService = currencyService; _taxService = taxService; - _priceFormatter = priceFormatter; _categoryService = categoryService; _productAttributeParser = productAttributeParser; + _productAttributeService = productAttributeService; + _productTemplateService = productTemplateService; _productService = productService; - _dateTimeHelper = dateTimeHelper; + _orderService = orderService; + _manufacturerService = manufacturerService; + _customerService = customerService; + _addressService = addressService; + _countryService = countryService; + _shipmentService = shipmentService; + _genericAttributeService = genericAttributeService; + _emailAccountService = emailAccountService; + _emailSender = emailSender; + _deliveryTimeService = deliveryTimeService; + _quantityUnitService = quantityUnitService; + _customerRepository = customerRepository; + _subscriptionRepository = subscriptionRepository; + + _dataExchangeSettings = dataExchangeSettings; _mediaSettings = mediaSettings; + + T = NullLocalizer.Instance; } + public Localizer T { get; set; } + + #endregion + #region Utilities - private void SetProgress(DataExportTaskContext ctx, int loadedRecords) + private void SetProgress(DataExporterContext ctx, int loadedRecords) { - if (!ctx.IsPreview && ctx.TaskContext.ScheduleTask != null && loadedRecords > 0) + if (!ctx.IsPreview && loadedRecords > 0) { int totalRecords = ctx.RecordsPerStore.Sum(x => x.Value); @@ -84,23 +165,219 @@ private void SetProgress(DataExportTaskContext ctx, int loadedRecords) var msg = ctx.ProgressInfo.FormatInvariant(ctx.RecordCount, totalRecords); - ctx.TaskContext.SetProgress(ctx.RecordCount, totalRecords, msg, true); + ctx.Request.ProgressValueSetter.Invoke(ctx.RecordCount, totalRecords, msg); + } + } + + private void SetProgress(DataExporterContext ctx, string message) + { + if (!ctx.IsPreview && message.HasValue()) + { + ctx.Request.ProgressMessageSetter.Invoke(message); } } - private void SetProgress(DataExportTaskContext ctx, string message) + private IExportDataSegmenterProvider CreateSegmenter(DataExporterContext ctx, int pageIndex = 0) { - if (!ctx.IsPreview && ctx.TaskContext.ScheduleTask != null && message.HasValue()) + var offset = ctx.Profile.Offset + (pageIndex * PageSize); + + var limit = (ctx.IsPreview ? PageSize : ctx.Profile.Limit); + + var recordsPerSegment = (ctx.IsPreview ? 0 : ctx.Profile.BatchSize); + + var totalCount = ctx.Profile.Offset + ctx.RecordsPerStore.First(x => x.Key == ctx.Store.Id).Value; + + switch (ctx.Provider.Value.EntityType) { - ctx.TaskContext.SetProgress(null, message, true); + case ExportEntityType.Product: + ctx.ExecuteContext.Segmenter = new ExportDataSegmenter + ( + skip => GetProducts(ctx, skip), + entities => + { + // load data behind navigation properties for current queue in one go + ctx.ProductExportContext = new ProductExportContext(entities, + x => _productAttributeService.Value.GetProductVariantAttributesByProductIds(x, null), + x => _productAttributeService.Value.GetProductVariantAttributeCombinations(x), + x => _productService.Value.GetTierPricesByProductIds(x, (ctx.Projection.CurrencyId ?? 0) != 0 ? ctx.ContextCustomer : null, ctx.Store.Id), + x => _categoryService.Value.GetProductCategoriesByProductIds(x), + x => _manufacturerService.Value.GetProductManufacturersByProductIds(x), + x => _productService.Value.GetProductPicturesByProductIds(x), + x => _productService.Value.GetProductTagsByProductIds(x), + x => _productService.Value.GetAppliedDiscountsByProductIds(x), + x => _productService.Value.GetProductSpecificationAttributesByProductIds(x), + x => _productService.Value.GetBundleItemsByProductIds(x, true) + ); + }, + entity => Convert(ctx, entity), + offset, PageSize, limit, recordsPerSegment, totalCount + ); + break; + + case ExportEntityType.Order: + ctx.ExecuteContext.Segmenter = new ExportDataSegmenter + ( + skip => GetOrders(ctx, skip), + entities => + { + ctx.OrderExportContext = new OrderExportContext(entities, + x => _customerService.Value.GetCustomersByIds(x), + x => _customerService.Value.GetRewardPointsHistoriesByCustomerIds(x), + x => _addressService.Value.GetAddressByIds(x), + x => _orderService.Value.GetOrderItemsByOrderIds(x), + x => _shipmentService.Value.GetShipmentsByOrderIds(x) + ); + }, + entity => Convert(ctx, entity), + offset, PageSize, limit, recordsPerSegment, totalCount + ); + break; + + case ExportEntityType.Manufacturer: + ctx.ExecuteContext.Segmenter = new ExportDataSegmenter + ( + skip => GetManufacturers(ctx, skip), + entities => + { + ctx.ManufacturerExportContext = new ManufacturerExportContext(entities, + x => _manufacturerService.Value.GetProductManufacturersByManufacturerIds(x), + x => _pictureService.Value.GetPicturesByIds(x) + ); + }, + entity => Convert(ctx, entity), + offset, PageSize, limit, recordsPerSegment, totalCount + ); + break; + + case ExportEntityType.Category: + ctx.ExecuteContext.Segmenter = new ExportDataSegmenter + ( + skip => GetCategories(ctx, skip), + entities => + { + ctx.CategoryExportContext = new CategoryExportContext(entities, + x => _categoryService.Value.GetProductCategoriesByCategoryIds(x), + x => _pictureService.Value.GetPicturesByIds(x) + ); + }, + entity => Convert(ctx, entity), + offset, PageSize, limit, recordsPerSegment, totalCount + ); + break; + + case ExportEntityType.Customer: + ctx.ExecuteContext.Segmenter = new ExportDataSegmenter + ( + skip => GetCustomers(ctx, skip), + entities => + { + ctx.CustomerExportContext = new CustomerExportContext(entities, + x => _genericAttributeService.Value.GetAttributesForEntity(x, "Customer") + ); + }, + entity => Convert(ctx, entity), + offset, PageSize, limit, recordsPerSegment, totalCount + ); + break; + + case ExportEntityType.NewsLetterSubscription: + ctx.ExecuteContext.Segmenter = new ExportDataSegmenter + ( + skip => GetNewsLetterSubscriptions(ctx, skip), + null, + entity => Convert(ctx, entity), + offset, PageSize, limit, recordsPerSegment, totalCount + ); + break; + + default: + ctx.ExecuteContext.Segmenter = null; + break; } + + return ctx.ExecuteContext.Segmenter as IExportDataSegmenterProvider; + } + + private bool CallProvider(DataExporterContext ctx, string streamId, string method, string path) + { + if (method != "Execute" && method != "OnExecuted") + throw new SmartException("Unknown export method {0}".FormatInvariant(method.NaIfEmpty())); + + try + { + ctx.ExecuteContext.DataStreamId = streamId; + + using (ctx.ExecuteContext.DataStream = new MemoryStream()) + { + if (method == "Execute") + { + ctx.Provider.Value.Execute(ctx.ExecuteContext); + } + else if (method == "OnExecuted") + { + ctx.Provider.Value.OnExecuted(ctx.ExecuteContext); + } + + if (ctx.IsFileBasedExport && path.HasValue()) + { + if (!ctx.ExecuteContext.DataStream.CanSeek) + ctx.Log.Warning("Data stream seems to be closed!"); + + ctx.ExecuteContext.DataStream.Seek(0, SeekOrigin.Begin); + + using (_rwLock.GetWriteLock()) + using (var fileStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.ReadWrite)) + { + ctx.Log.Information("Creating file " + path); + + ctx.ExecuteContext.DataStream.CopyTo(fileStream); + } + } + } + } + catch (Exception exc) + { + ctx.ExecuteContext.Abort = ExportAbortion.Hard; + ctx.Log.Error("The provider failed at the {0} method: {1}".FormatInvariant(method, exc.ToAllMessages()), exc); + ctx.Result.LastError = exc.ToString(); + } + finally + { + if (ctx.ExecuteContext.DataStream != null) + { + ctx.ExecuteContext.DataStream.Dispose(); + ctx.ExecuteContext.DataStream = null; + } + } + + return (ctx.ExecuteContext.Abort != ExportAbortion.Hard); + } + + private void SendCompletionEmail(DataExporterContext ctx) + { + var emailAccount = _emailAccountService.Value.GetEmailAccountById(ctx.Profile.EmailAccountId); + var smtpContext = new SmtpContext(emailAccount); + var message = new EmailMessage(); + + var storeInfo = "{0} ({1})".FormatInvariant(ctx.Store.Name, ctx.Store.Url); + + message.To.AddRange(ctx.Profile.CompletedEmailAddresses.SplitSafe(",").Where(x => x.IsEmail()).Select(x => new EmailAddress(x))); + message.From = new EmailAddress(emailAccount.Email, emailAccount.DisplayName); + + message.Subject = _services.Localization.GetResource("Admin.DataExchange.Export.CompletedEmail.Subject", ctx.Projection.LanguageId ?? 0) + .FormatInvariant(ctx.Profile.Name); + + message.Body = _services.Localization.GetResource("Admin.DataExchange.Export.CompletedEmail.Body", ctx.Projection.LanguageId ?? 0) + .FormatInvariant(storeInfo); + + _emailSender.Value.SendEmail(smtpContext, message); } #endregion #region Getting data - private IQueryable GetProductQuery(DataExportTaskContext ctx, int skip, int take) + private IQueryable GetProductQuery(DataExporterContext ctx, int skip, int take) { IQueryable query = null; @@ -134,12 +411,12 @@ private IQueryable GetProductQuery(DataExportTaskContext ctx, int skip, searchContext.CategoryIds = ctx.Filter.CategoryIds.ToList(); if (ctx.Filter.CreatedFrom.HasValue) - searchContext.CreatedFromUtc = _dateTimeHelper.ConvertToUtcTime(ctx.Filter.CreatedFrom.Value, _dateTimeHelper.CurrentTimeZone); + searchContext.CreatedFromUtc = _dateTimeHelper.Value.ConvertToUtcTime(ctx.Filter.CreatedFrom.Value, _dateTimeHelper.Value.CurrentTimeZone); if (ctx.Filter.CreatedTo.HasValue) - searchContext.CreatedToUtc = _dateTimeHelper.ConvertToUtcTime(ctx.Filter.CreatedTo.Value, _dateTimeHelper.CurrentTimeZone); + searchContext.CreatedToUtc = _dateTimeHelper.Value.ConvertToUtcTime(ctx.Filter.CreatedTo.Value, _dateTimeHelper.Value.CurrentTimeZone); - query = _productService.PrepareProductSearchQuery(searchContext); + query = _productService.Value.PrepareProductSearchQuery(searchContext); query = query.OrderByDescending(x => x.CreatedOnUtc); } @@ -157,7 +434,7 @@ private IQueryable GetProductQuery(DataExportTaskContext ctx, int skip, return query; } - private List GetProducts(DataExportTaskContext ctx, int skip) + private List GetProducts(DataExporterContext ctx, int skip) { var result = new List(); @@ -182,7 +459,7 @@ private List GetProducts(DataExportTaskContext ctx, int skip) ParentGroupedProductId = product.Id }; - foreach (var associatedProduct in _productService.SearchProducts(associatedSearchContext)) + foreach (var associatedProduct in _productService.Value.SearchProducts(associatedSearchContext)) { result.Add(associatedProduct); } @@ -205,8 +482,568 @@ private List GetProducts(DataExportTaskContext ctx, int skip) return result; } + private IQueryable GetOrderQuery(DataExporterContext ctx, int skip, int take) + { + var query = _orderService.Value.GetOrders( + ctx.Profile.PerStore ? ctx.Store.Id : ctx.Filter.StoreId, + ctx.Projection.CustomerId ?? 0, + ctx.Filter.CreatedFrom.HasValue ? (DateTime?)_dateTimeHelper.Value.ConvertToUtcTime(ctx.Filter.CreatedFrom.Value, _dateTimeHelper.Value.CurrentTimeZone) : null, + ctx.Filter.CreatedTo.HasValue ? (DateTime?)_dateTimeHelper.Value.ConvertToUtcTime(ctx.Filter.CreatedTo.Value, _dateTimeHelper.Value.CurrentTimeZone) : null, + ctx.Filter.OrderStatusIds, + ctx.Filter.PaymentStatusIds, + ctx.Filter.ShippingStatusIds, + null, + null, + null); + + if (ctx.EntityIdsSelected.Count > 0) + query = query.Where(x => ctx.EntityIdsSelected.Contains(x.Id)); + + query = query.OrderByDescending(x => x.CreatedOnUtc); + + if (skip > 0) + query = query.Skip(skip); + + if (take != int.MaxValue) + query = query.Take(take); + + return query; + } + + private List GetOrders(DataExporterContext ctx, int skip) + { + var orders = GetOrderQuery(ctx, skip, PageSize).ToList(); + + if (ctx.Projection.OrderStatusChange != ExportOrderStatusChange.None) + { + ctx.EntityIdsLoaded = ctx.EntityIdsLoaded + .Union(orders.Select(x => x.Id)) + .Distinct() + .ToList(); + } + + try + { + SetProgress(ctx, orders.Count); + + _services.DbContext.DetachEntities(orders); + } + catch { } + + return orders; + } + + private IQueryable GetManufacturerQuery(DataExporterContext ctx, int skip, int take) + { + var showHidden = !ctx.Filter.IsPublished.HasValue; + var storeId = (ctx.Profile.PerStore ? ctx.Store.Id : ctx.Filter.StoreId); + + var query = _manufacturerService.Value.GetManufacturers(showHidden, storeId); + + query = query.OrderBy(x => x.DisplayOrder); + + if (skip > 0) + query = query.Skip(skip); + + if (take != int.MaxValue) + query = query.Take(take); + + return query; + } + + private List GetManufacturers(DataExporterContext ctx, int skip) + { + var manus = GetManufacturerQuery(ctx, skip, PageSize).ToList(); + + try + { + SetProgress(ctx, manus.Count); + + _services.DbContext.DetachEntities(manus); + } + catch { } + + return manus; + } + + private IQueryable GetCategoryQuery(DataExporterContext ctx, int skip, int take) + { + var showHidden = !ctx.Filter.IsPublished.HasValue; + var storeId = (ctx.Profile.PerStore ? ctx.Store.Id : ctx.Filter.StoreId); + + var query = _categoryService.Value.GetCategories(null, showHidden, null, true, storeId); + + query = query + .OrderBy(x => x.ParentCategoryId) + .ThenBy(x => x.DisplayOrder); + + if (skip > 0) + query = query.Skip(skip); + + if (take != int.MaxValue) + query = query.Take(take); + + return query; + } + + private List GetCategories(DataExporterContext ctx, int skip) + { + var categories = GetCategoryQuery(ctx, skip, PageSize).ToList(); + + try + { + SetProgress(ctx, categories.Count); + + _services.DbContext.DetachEntities(categories); + } + catch { } + + return categories; + } + + private IQueryable GetCustomerQuery(DataExporterContext ctx, int skip, int take) + { + var query = _customerRepository.Value.TableUntracked + .Expand(x => x.BillingAddress) + .Expand(x => x.ShippingAddress) + .Expand(x => x.Addresses.Select(y => y.Country)) + .Expand(x => x.Addresses.Select(y => y.StateProvince)) + .Expand(x => x.CustomerRoles) + .Where(x => !x.Deleted); + + if (ctx.EntityIdsSelected.Count > 0) + { + query = query.Where(x => ctx.EntityIdsSelected.Contains(x.Id)); + } + + query = query.OrderByDescending(x => x.CreatedOnUtc); + + if (skip > 0) + query = query.Skip(skip); + + if (take != int.MaxValue) + query = query.Take(take); + + return query; + } + + private List GetCustomers(DataExporterContext ctx, int skip) + { + var customers = GetCustomerQuery(ctx, skip, PageSize).ToList(); + + try + { + SetProgress(ctx, customers.Count); + + _services.DbContext.DetachEntities(customers); + } + catch { } + + return customers; + } + + private IQueryable GetNewsLetterSubscriptionQuery(DataExporterContext ctx, int skip, int take) + { + var storeId = (ctx.Profile.PerStore ? ctx.Store.Id : ctx.Filter.StoreId); + + var query = _subscriptionRepository.Value.TableUntracked; + + if (storeId > 0) + { + query = query.Where(x => x.StoreId == storeId); + } + + query = query + .OrderBy(x => x.StoreId) + .ThenBy(x => x.Email); + + if (skip > 0) + query = query.Skip(skip); + + if (take != int.MaxValue) + query = query.Take(take); + + return query; + } + + private List GetNewsLetterSubscriptions(DataExporterContext ctx, int skip) + { + var subscriptions = GetNewsLetterSubscriptionQuery(ctx, skip, PageSize).ToList(); + + try + { + SetProgress(ctx, subscriptions.Count); + + _services.DbContext.DetachEntities(subscriptions); + } + catch { } + + return subscriptions; + } + #endregion + private List Init(DataExporterContext ctx, int? totalRecords = null) + { + // Init base things that are even required for preview. Init all other things (regular export) in ExportCoreOuter. + List result = null; + + if (ctx.Projection.CurrencyId.HasValue) + ctx.ContextCurrency = _currencyService.Value.GetCurrencyById(ctx.Projection.CurrencyId.Value); + else + ctx.ContextCurrency = _services.WorkContext.WorkingCurrency; + + if (ctx.Projection.CustomerId.HasValue) + ctx.ContextCustomer = _customerService.Value.GetCustomerById(ctx.Projection.CustomerId.Value); + else + ctx.ContextCustomer = _services.WorkContext.CurrentCustomer; + + if (ctx.Projection.LanguageId.HasValue) + ctx.ContextLanguage = _languageService.Value.GetLanguageById(ctx.Projection.LanguageId.Value); + else + ctx.ContextLanguage = _services.WorkContext.WorkingLanguage; + + ctx.Stores = _services.StoreService.GetAllStores().ToDictionary(x => x.Id, x => x); + ctx.Languages = _languageService.Value.GetAllLanguages(true).ToDictionary(x => x.Id, x => x); + + if (!ctx.IsPreview && ctx.Profile.PerStore) + { + result = new List(ctx.Stores.Values.Where(x => x.Id == ctx.Filter.StoreId || ctx.Filter.StoreId == 0)); + } + else + { + int? storeId = (ctx.Filter.StoreId == 0 ? ctx.Projection.StoreId : ctx.Filter.StoreId); + + ctx.Store = ctx.Stores.Values.FirstOrDefault(x => x.Id == (storeId ?? _services.StoreContext.CurrentStore.Id)); + + result = new List { ctx.Store }; + } + + // get total records for progress + foreach (var store in result) + { + ctx.Store = store; + + int totalCount = 0; + + if (totalRecords.HasValue) + { + totalCount = totalRecords.Value; // speed up preview by not counting total at each page + } + else + { + switch (ctx.Provider.Value.EntityType) + { + case ExportEntityType.Product: + totalCount = GetProductQuery(ctx, ctx.Profile.Offset, int.MaxValue).Count(); + break; + case ExportEntityType.Order: + totalCount = GetOrderQuery(ctx, ctx.Profile.Offset, int.MaxValue).Count(); + break; + case ExportEntityType.Manufacturer: + totalCount = GetManufacturerQuery(ctx, ctx.Profile.Offset, int.MaxValue).Count(); + break; + case ExportEntityType.Category: + totalCount = GetCategoryQuery(ctx, ctx.Profile.Offset, int.MaxValue).Count(); + break; + case ExportEntityType.Customer: + totalCount = GetCustomerQuery(ctx, ctx.Profile.Offset, int.MaxValue).Count(); + break; + case ExportEntityType.NewsLetterSubscription: + totalCount = GetNewsLetterSubscriptionQuery(ctx, ctx.Profile.Offset, int.MaxValue).Count(); + break; + } + } + + ctx.RecordsPerStore.Add(store.Id, totalCount); + } + + return result; + } + + private void ExportCoreInner(DataExporterContext ctx, Store store) + { + if (ctx.ExecuteContext.Abort != ExportAbortion.None) + return; + + int fileIndex = 0; + + ctx.Store = store; + + { + var logHead = new StringBuilder(); + logHead.AppendLine(); + logHead.AppendLine(new string('-', 40)); + logHead.AppendLine("SmartStore.NET:\t\tv." + SmartStoreVersion.CurrentFullVersion); + logHead.Append("Export profile:\t\t" + ctx.Profile.Name); + logHead.AppendLine(ctx.Profile.Id == 0 ? " (volatile)" : " (Id {0})".FormatInvariant(ctx.Profile.Id)); + + logHead.AppendLine("Export provider:\t{0} ({1})".FormatInvariant(ctx.Provider.Metadata.FriendlyName, ctx.Profile.ProviderSystemName)); + + var plugin = ctx.Provider.Metadata.PluginDescriptor; + logHead.Append("Plugin:\t\t\t\t"); + logHead.AppendLine(plugin == null ? "".NaIfEmpty() : "{0} ({1}) v.{2}".FormatInvariant(plugin.FriendlyName, plugin.SystemName, plugin.Version.ToString())); + + logHead.AppendLine("Entity:\t\t\t\t" + ctx.Provider.Value.EntityType.ToString()); + + var storeInfo = (ctx.Profile.PerStore ? "{0} (Id {1})".FormatInvariant(ctx.Store.Name, ctx.Store.Id) : "All stores"); + logHead.Append("Store:\t\t\t\t" + storeInfo); + + ctx.Log.Information(logHead.ToString()); + } + + ctx.ExecuteContext.Store = ToDynamic(ctx, ctx.Store); + + ctx.ExecuteContext.MaxFileNameLength = _dataExchangeSettings.Value.MaxFileNameLength; + + ctx.ExecuteContext.HasPublicDeployment = ctx.Profile.Deployments.Any(x => x.IsPublic && x.DeploymentType == ExportDeploymentType.FileSystem); + + ctx.ExecuteContext.PublicFolderPath = (ctx.ExecuteContext.HasPublicDeployment ? Path.Combine(HttpRuntime.AppDomainAppPath, PublicFolder) : null); + + var fileExtension = (ctx.Provider.Value.FileExtension.HasValue() ? ctx.Provider.Value.FileExtension.ToLower().EnsureStartsWith(".") : ""); + + + using (var segmenter = CreateSegmenter(ctx)) + { + if (segmenter == null) + { + throw new SmartException("Unsupported entity type '{0}'".FormatInvariant(ctx.Provider.Value.EntityType.ToString())); + } + + if (segmenter.TotalRecords <= 0) + { + ctx.Log.Information("There are no records to export"); + } + + while (ctx.ExecuteContext.Abort == ExportAbortion.None && segmenter.HasData) + { + segmenter.RecordPerSegmentCount = 0; + ctx.ExecuteContext.RecordsSucceeded = 0; + + string path = null; + + if (ctx.IsFileBasedExport) + { + var resolvedPattern = ctx.Profile.ResolveFileNamePattern(ctx.Store, ++fileIndex, ctx.ExecuteContext.MaxFileNameLength); + + ctx.ExecuteContext.FileName = resolvedPattern + fileExtension; + path = Path.Combine(ctx.ExecuteContext.Folder, ctx.ExecuteContext.FileName); + + if (ctx.ExecuteContext.HasPublicDeployment) + ctx.ExecuteContext.PublicFileUrl = ctx.Store.Url.EnsureEndsWith("/") + PublicFolder.EnsureEndsWith("/") + ctx.ExecuteContext.FileName; + } + + if (CallProvider(ctx, null, "Execute", path)) + { + ctx.Log.Information("Provider reports {0} successful exported record(s)".FormatInvariant(ctx.ExecuteContext.RecordsSucceeded)); + + // create info for deployment list in profile edit + if (ctx.IsFileBasedExport) + { + ctx.Result.Files.Add(new DataExportResult.ExportFileInfo + { + StoreId = ctx.Store.Id, + FileName = ctx.ExecuteContext.FileName + }); + } + } + + if (ctx.ExecuteContext.IsMaxFailures) + ctx.Log.Warning("Export aborted. The maximum number of failures has been reached"); + + if (ctx.CancellationToken.IsCancellationRequested) + ctx.Log.Warning("Export aborted. A cancellation has been requested"); + } + + if (ctx.ExecuteContext.Abort != ExportAbortion.Hard) + { + // always call OnExecuted + if (ctx.ExecuteContext.ExtraDataStreams.Count == 0) + ctx.ExecuteContext.ExtraDataStreams.Add(new ExportExtraStreams()); + + ctx.ExecuteContext.ExtraDataStreams.ForEach(x => + { + var path = (x.FileName.HasValue() ? Path.Combine(ctx.ExecuteContext.Folder, x.FileName) : null); + + CallProvider(ctx, x.Id, "OnExecuted", path); + }); + + ctx.ExecuteContext.ExtraDataStreams.Clear(); + } + } + } + + private void ExportCoreOuter(DataExporterContext ctx) + { + if (ctx.Profile == null || !ctx.Profile.Enabled) + return; + + FileSystemHelper.Delete(ctx.LogPath); + FileSystemHelper.ClearDirectory(ctx.FolderContent, false); + FileSystemHelper.Delete(ctx.ZipPath); + + using (var logger = new TraceLogger(ctx.LogPath)) + { + try + { + if (!ctx.Provider.IsValid()) + { + throw new SmartException("Export aborted because the export provider is not valid"); + } + + ctx.Log = logger; + ctx.ExecuteContext.Log = logger; + ctx.ProgressInfo = T("Admin.DataExchange.Export.ProgressInfo"); + + if (ctx.Profile.ProviderConfigData.HasValue()) + { + var configInfo = ctx.Provider.Value.ConfigurationInfo; + if (configInfo != null) + { + ctx.ExecuteContext.ConfigurationData = XmlHelper.Deserialize(ctx.Profile.ProviderConfigData, configInfo.ModelType); + } + } + + // TODO: lazyLoading: false. It requires IDbContextExtensions::Load/QueryFor for properties internally mapped by EF + using (var scope = new DbContextScope(_services.DbContext, autoDetectChanges: false, proxyCreation: false, validateOnSave: false, forceNoTracking: true)) + { + ctx.DeliveryTimes = _deliveryTimeService.Value.GetAllDeliveryTimes().ToDictionary(x => x.Id); + ctx.QuantityUnits = _quantityUnitService.Value.GetAllQuantityUnits().ToDictionary(x => x.Id); + ctx.ProductTemplates = _productTemplateService.Value.GetAllProductTemplates().ToDictionary(x => x.Id); + + if (ctx.Provider.Value.EntityType == ExportEntityType.Product) + { + var allCategories = _categoryService.Value.GetAllCategories(showHidden: true, applyNavigationFilters: false); + ctx.Categories = allCategories.ToDictionary(x => x.Id); + } + + if (ctx.Provider.Value.EntityType == ExportEntityType.Order) + { + ctx.Countries = _countryService.Value.GetAllCountries(true).ToDictionary(x => x.Id, x => x); + } + + if (ctx.Provider.Value.EntityType == ExportEntityType.Customer) + { + var subscriptionEmails = _subscriptionRepository.Value.TableUntracked + .Where(x => x.Active) + .Select(x => x.Email) + .Distinct() + .ToList(); + + ctx.NewsletterSubscriptions = new HashSet(subscriptionEmails, StringComparer.OrdinalIgnoreCase); + } + + var stores = Init(ctx); + + ctx.ExecuteContext.Language = ToDynamic(ctx, ctx.ContextLanguage); + ctx.ExecuteContext.Customer = ToDynamic(ctx, ctx.ContextCustomer); + ctx.ExecuteContext.Currency = ToDynamic(ctx, ctx.ContextCurrency); + + stores.ForEach(x => ExportCoreInner(ctx, x)); + } + + if (!ctx.IsPreview && ctx.ExecuteContext.Abort != ExportAbortion.Hard) + { + if (ctx.IsFileBasedExport) + { + if (ctx.Profile.CreateZipArchive || ctx.Profile.Deployments.Any(x => x.Enabled && x.CreateZip)) + { + ZipFile.CreateFromDirectory(ctx.FolderContent, ctx.ZipPath, CompressionLevel.Fastest, true); + } + + SetProgress(ctx, T("Common.Deployment")); + + // TODO: deployment + //foreach (var deployment in ctx.Profile.Deployments.OrderBy(x => x.DeploymentTypeId).Where(x => x.Enabled)) + //{ + // try + // { + // switch (deployment.DeploymentType) + // { + // case ExportDeploymentType.FileSystem: + // DeployFileSystem(ctx, deployment); + // break; + // case ExportDeploymentType.Email: + // DeployEmail(ctx, deployment); + // break; + // case ExportDeploymentType.Http: + // DeployHttp(ctx, deployment); + // break; + // case ExportDeploymentType.Ftp: + // DeployFtp(ctx, deployment); + // break; + // } + // } + // catch (Exception exc) + // { + // logger.Error("Deployment \"{0}\" of type {1} failed: {2}".FormatInvariant( + // deployment.Name, deployment.DeploymentType.ToString(), exc.Message), exc); + // } + //} + } + + if (ctx.Profile.EmailAccountId != 0 && ctx.Profile.CompletedEmailAddresses.HasValue()) + { + SendCompletionEmail(ctx); + } + } + } + catch (Exception exc) + { + logger.Error(exc); + ctx.Result.LastError = exc.ToString(); + } + finally + { + try + { + if (!ctx.IsPreview && ctx.Profile.Id != 0) + { + ctx.Profile.ResultInfo = XmlHelper.Serialize(ctx.Result); + + _exportProfileService.Value.UpdateExportProfile(ctx.Profile); + } + } + catch { } + + try + { + if (ctx.IsFileBasedExport && ctx.ExecuteContext.Abort != ExportAbortion.Hard && ctx.Profile.Cleanup) + { + FileSystemHelper.ClearDirectory(ctx.FolderContent, false); + } + } + catch { } + + try + { + ctx.NewsletterSubscriptions.Clear(); + ctx.ProductTemplates.Clear(); + ctx.Countries.Clear(); + ctx.Stores.Clear(); + ctx.QuantityUnits.Clear(); + ctx.DeliveryTimes.Clear(); + ctx.CategoryPathes.Clear(); + ctx.Categories.Clear(); + ctx.EntityIdsSelected.Clear(); + ctx.ProductExportContext = null; + ctx.OrderExportContext = null; + ctx.ManufacturerExportContext = null; + ctx.CategoryExportContext = null; + ctx.CustomerExportContext = null; + + ctx.ExecuteContext.CustomProperties.Clear(); + ctx.ExecuteContext.Log = null; + ctx.Log = null; + } + catch { } + } + } + + if (ctx.IsPreview || ctx.ExecuteContext.Abort == ExportAbortion.Hard) + return; + } + /// /// The name of the public export folder /// diff --git a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporterContext.cs b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporterContext.cs new file mode 100644 index 0000000000..cb95e67f23 --- /dev/null +++ b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporterContext.cs @@ -0,0 +1,218 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading; +using SmartStore.Core; +using SmartStore.Core.Domain; +using SmartStore.Core.Domain.Catalog; +using SmartStore.Core.Domain.Customers; +using SmartStore.Core.Domain.DataExchange; +using SmartStore.Core.Domain.Directory; +using SmartStore.Core.Domain.Localization; +using SmartStore.Core.Domain.Stores; +using SmartStore.Core.Logging; +using SmartStore.Core.Plugins; +using SmartStore.Utilities; + +namespace SmartStore.Services.DataExchange.Internal +{ + internal class DataExporterContext + { + private ProductExportContext _productExportContext; + private OrderExportContext _orderExportContext; + private ManufacturerExportContext _manufacturerExportContext; + private CategoryExportContext _categoryExportContext; + private CustomerExportContext _customerExportContext; + + public DataExporterContext( + DataExportRequest request, + CancellationToken cancellationToken, + ExportProfile profile, + Provider provider, + string selectedIds = null, + Action previewData = null) + { + Request = request; + CancellationToken = cancellationToken; + Profile = profile; + Provider = provider; + Filter = XmlHelper.Deserialize(profile.Filtering); + Projection = XmlHelper.Deserialize(profile.Projection); + EntityIdsSelected = selectedIds.SplitSafe(",").Select(x => x.ToInt()).ToList(); + PreviewData = previewData; + + FolderContent = FileSystemHelper.TempDir(@"Profile\Export\{0}\Content".FormatInvariant(profile.FolderName)); + FolderRoot = System.IO.Directory.GetParent(FolderContent).FullName; + + Categories = new Dictionary(); + CategoryPathes = new Dictionary(); + Countries = new Dictionary(); + ProductTemplates = new Dictionary(); + NewsletterSubscriptions = new HashSet(); + + RecordsPerStore = new Dictionary(); + EntityIdsLoaded = new List(); + + Result = new DataExportResult + { + FileFolder = (IsFileBasedExport ? FolderContent : null) + }; + + ExecuteContext = new ExportExecuteContext(Result, CancellationToken, FolderContent); + ExecuteContext.Projection = XmlHelper.Deserialize(profile.Projection); + } + + public List EntityIdsSelected { get; private set; } + public List EntityIdsLoaded { get; set; } + + public int RecordCount { get; set; } + public Dictionary RecordsPerStore { get; set; } + public string ProgressInfo { get; set; } + public IQueryable QueryProducts { get; set; } + + public Action PreviewData { get; private set; } + public bool IsPreview + { + get { return PreviewData != null; } + } + + public DataExportRequest Request { get; private set; } + public CancellationToken CancellationToken { get; private set; } + public ExportProfile Profile { get; private set; } + public Provider Provider { get; private set; } + + public bool Supports(ExportFeatures feature) + { + return (!IsPreview && Provider.Metadata.ExportFeatures.HasFlag(feature)); + } + + public ExportFilter Filter { get; private set; } + public ExportProjection Projection { get; private set; } + public Currency ContextCurrency { get; set; } + public Customer ContextCustomer { get; set; } + public Language ContextLanguage { get; set; } + + public TraceLogger Log { get; set; } + public Store Store { get; set; } + + public string FolderRoot { get; private set; } + public string FolderContent { get; private set; } + public string ZipName + { + get { return Profile.FolderName + ".zip"; } + } + public string ZipPath + { + get { return Path.Combine(FolderRoot, ZipName); } + } + public string LogPath + { + get { return Path.Combine(FolderRoot, "log.txt"); } + } + + public bool IsFileBasedExport + { + get { return Provider == null || Provider.Value == null || Provider.Value.FileExtension.HasValue(); } + } + public string[] GetDeploymentFiles(ExportDeployment deployment) + { + if (!IsFileBasedExport) + return new string[0]; + + if (deployment.CreateZip) + return new string[] { ZipPath }; + + return System.IO.Directory.GetFiles(FolderContent, "*.*", SearchOption.AllDirectories); + } + + // data loaded once per export + public Dictionary Categories { get; set; } + public Dictionary CategoryPathes { get; set; } + public Dictionary DeliveryTimes { get; set; } + public Dictionary QuantityUnits { get; set; } + public Dictionary Stores { get; set; } + public Dictionary Languages { get; set; } + public Dictionary Countries { get; set; } + public Dictionary ProductTemplates { get; set; } + public HashSet NewsletterSubscriptions { get; set; } + + // data loaded once per page + public ProductExportContext ProductExportContext + { + get + { + return _productExportContext; + } + set + { + if (_productExportContext != null) + _productExportContext.Clear(); + + _productExportContext = value; + } + } + + public OrderExportContext OrderExportContext + { + get + { + return _orderExportContext; + } + set + { + if (_orderExportContext != null) + _orderExportContext.Clear(); + + _orderExportContext = value; + } + } + + public ManufacturerExportContext ManufacturerExportContext + { + get + { + return _manufacturerExportContext; + } + set + { + if (_manufacturerExportContext != null) + _manufacturerExportContext.Clear(); + + _manufacturerExportContext = value; + } + } + + public CategoryExportContext CategoryExportContext + { + get + { + return _categoryExportContext; + } + set + { + if (_categoryExportContext != null) + _categoryExportContext.Clear(); + + _categoryExportContext = value; + } + } + public CustomerExportContext CustomerExportContext + { + get + { + return _customerExportContext; + } + set + { + if (_customerExportContext != null) + _customerExportContext.Clear(); + + _customerExportContext = value; + } + } + + public ExportExecuteContext ExecuteContext { get; set; } + public DataExportResult Result { get; set; } + } +} diff --git a/src/Libraries/SmartStore.Services/DataExchange/Internal/DynamicEntityHelper.cs b/src/Libraries/SmartStore.Services/DataExchange/Internal/DynamicEntityHelper.cs index c1ebf6a7a5..e3de6b5e56 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Internal/DynamicEntityHelper.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Internal/DynamicEntityHelper.cs @@ -28,7 +28,7 @@ namespace SmartStore.Services.DataExchange.Internal { public partial class DataExporter { - private void PrepareProductDescription(DataExportTaskContext ctx, dynamic dynObject, Product product) + private void PrepareProductDescription(DataExporterContext ctx, dynamic dynObject, Product product) { try { @@ -118,25 +118,25 @@ private void PrepareProductDescription(DataExportTaskContext ctx, dynamic dynObj catch { } } - private decimal? ConvertPrice(DataExportTaskContext ctx, Product product, decimal? price) + private decimal? ConvertPrice(DataExporterContext ctx, Product product, decimal? price) { if (price.HasValue) { if (ctx.Projection.ConvertNetToGrossPrices) { decimal taxRate; - price = _taxService.GetProductPrice(product, price.Value, true, ctx.ContextCustomer, out taxRate); + price = _taxService.Value.GetProductPrice(product, price.Value, true, ctx.ContextCustomer, out taxRate); } if (price != decimal.Zero) { - price = _currencyService.ConvertFromPrimaryStoreCurrency(price.Value, ctx.ContextCurrency, ctx.Store); + price = _currencyService.Value.ConvertFromPrimaryStoreCurrency(price.Value, ctx.ContextCurrency, ctx.Store); } } return price; } - private decimal CalculatePrice(DataExportTaskContext ctx, Product product, bool forAttributeCombination) + private decimal CalculatePrice(DataExporterContext ctx, Product product, bool forAttributeCombination) { decimal price = product.Price; @@ -148,22 +148,22 @@ private decimal CalculatePrice(DataExportTaskContext ctx, Product product, bool if (ctx.Projection.PriceType.Value == PriceDisplayType.LowestPrice) { bool displayFromMessage; - price = _priceCalculationService.GetLowestPrice(product, priceCalculationContext, out displayFromMessage); + price = _priceCalculationService.Value.GetLowestPrice(product, priceCalculationContext, out displayFromMessage); } else if (ctx.Projection.PriceType.Value == PriceDisplayType.PreSelectedPrice) { - price = _priceCalculationService.GetPreselectedPrice(product, priceCalculationContext); + price = _priceCalculationService.Value.GetPreselectedPrice(product, priceCalculationContext); } else if (ctx.Projection.PriceType.Value == PriceDisplayType.PriceWithoutDiscountsAndAttributes) { - price = _priceCalculationService.GetFinalPrice(product, null, ctx.ContextCustomer, decimal.Zero, false, 1, null, priceCalculationContext); + price = _priceCalculationService.Value.GetFinalPrice(product, null, ctx.ContextCustomer, decimal.Zero, false, 1, null, priceCalculationContext); } } return ConvertPrice(ctx, product, price) ?? price; } - private void MergeWithCombination(DataExportTaskContext ctx, dynamic dynObject, Product product, + private void MergeWithCombination(DataExporterContext ctx, dynamic dynObject, Product product, ICollection productAttributes, ProductVariantAttributeCombination combination) { product.MergeWithCombination(combination); @@ -172,13 +172,13 @@ private void MergeWithCombination(DataExportTaskContext ctx, dynamic dynObject, if (combination != null && ctx.Projection.AttributeCombinationValueMerging == ExportAttributeValueMerging.AppendAllValuesToName) { - var values = _productAttributeParser.ParseProductVariantAttributeValues(combination.AttributesXml, productAttributes, ctx.Projection.LanguageId ?? 0); + var values = _productAttributeParser.Value.ParseProductVariantAttributeValues(combination.AttributesXml, productAttributes, ctx.Projection.LanguageId ?? 0); dynObject.Name = ((string)dynObject.Name).Grow(string.Join(", ", values), " "); } - dynObject._BasePriceInfo = product.GetBasePriceInfo(_services.Localization, _priceFormatter, _currencyService, _taxService, - _priceCalculationService, ctx.ContextCurrency, decimal.Zero, true); + dynObject._BasePriceInfo = product.GetBasePriceInfo(_services.Localization, _priceFormatter.Value, _currencyService.Value, _taxService.Value, + _priceCalculationService.Value, ctx.ContextCurrency, decimal.Zero, true); // navigation properties ToDeliveryTime(ctx, dynObject, product.DeliveryTimeId); @@ -212,7 +212,7 @@ private void MergeWithCombination(DataExportTaskContext ctx, dynamic dynObject, if (ctx.Projection.ConvertNetToGrossPrices) { decimal taxRate; - dynObject._OldPrice = _taxService.GetProductPrice(product, product.OldPrice, true, ctx.ContextCustomer, out taxRate); + dynObject._OldPrice = _taxService.Value.GetProductPrice(product, product.OldPrice, true, ctx.ContextCustomer, out taxRate); } else { @@ -232,7 +232,7 @@ private void MergeWithCombination(DataExportTaskContext ctx, dynamic dynObject, if (!(product.ProductType == ProductType.BundledProduct && product.BundlePerItemPricing)) { - var specialPrice = _priceCalculationService.GetSpecialPrice(product); + var specialPrice = _priceCalculationService.Value.GetSpecialPrice(product); dynObject._SpecialPrice = ConvertPrice(ctx, product, specialPrice); @@ -248,7 +248,7 @@ private void MergeWithCombination(DataExportTaskContext ctx, dynamic dynObject, } - private List GetLocalized(DataExportTaskContext ctx, T entity, params Expression>[] keySelectors) + private List GetLocalized(DataExporterContext ctx, T entity, params Expression>[] keySelectors) where T : BaseEntity, ILocalizedEntity { if (ctx.Languages.Count <= 1) @@ -266,7 +266,7 @@ private List GetLocalized(DataExportTaskContext ctx, T entity, param // add SeName if (isSlugSupported) { - var value = _urlRecordService.GetActiveSlug(entity.Id, localeKeyGroup, language.Value.Id); + var value = _urlRecordService.Value.GetActiveSlug(entity.Id, localeKeyGroup, language.Value.Id); if (value.HasValue()) { dynamic exp = new HybridExpando(); @@ -283,7 +283,7 @@ private List GetLocalized(DataExportTaskContext ctx, T entity, param var member = keySelector.Body as MemberExpression; var propInfo = member.Member as PropertyInfo; string localeKey = propInfo.Name; - var value = _localizedEntityService.GetLocalizedValue(language.Value.Id, entity.Id, localeKeyGroup, localeKey); + var value = _localizedEntityService.Value.GetLocalizedValue(language.Value.Id, entity.Id, localeKeyGroup, localeKey); // we better not export empty values. the risk is to high that they are imported and unnecessary fill databases. if (value.HasValue()) @@ -301,7 +301,7 @@ private List GetLocalized(DataExportTaskContext ctx, T entity, param return (localized.Count == 0 ? null : localized); } - private dynamic ToDynamic(DataExportTaskContext ctx, Currency currency) + private dynamic ToDynamic(DataExporterContext ctx, Currency currency) { if (currency == null) return null; @@ -314,7 +314,7 @@ private dynamic ToDynamic(DataExportTaskContext ctx, Currency currency) return result; } - private dynamic ToDynamic(DataExportTaskContext ctx, Language language) + private dynamic ToDynamic(DataExporterContext ctx, Language language) { if (language == null) return null; @@ -323,7 +323,7 @@ private dynamic ToDynamic(DataExportTaskContext ctx, Language language) return result; } - private dynamic ToDynamic(DataExportTaskContext ctx, Country country) + private dynamic ToDynamic(DataExporterContext ctx, Country country) { if (country == null) return null; @@ -336,7 +336,7 @@ private dynamic ToDynamic(DataExportTaskContext ctx, Country country) return result; } - private dynamic ToDynamic(DataExportTaskContext ctx, Address address) + private dynamic ToDynamic(DataExporterContext ctx, Address address) { if (address == null) return null; @@ -362,7 +362,7 @@ private dynamic ToDynamic(DataExportTaskContext ctx, Address address) return result; } - private dynamic ToDynamic(DataExportTaskContext ctx, RewardPointsHistory points) + private dynamic ToDynamic(DataExporterContext ctx, RewardPointsHistory points) { if (points == null) return null; @@ -372,7 +372,7 @@ private dynamic ToDynamic(DataExportTaskContext ctx, RewardPointsHistory points) return result; } - private dynamic ToDynamic(DataExportTaskContext ctx, Customer customer) + private dynamic ToDynamic(DataExporterContext ctx, Customer customer) { if (customer == null) return null; @@ -393,7 +393,7 @@ private dynamic ToDynamic(DataExportTaskContext ctx, Customer customer) return result; } - private dynamic ToDynamic(DataExportTaskContext ctx, Store store) + private dynamic ToDynamic(DataExporterContext ctx, Store store) { if (store == null) return null; @@ -406,7 +406,7 @@ private dynamic ToDynamic(DataExportTaskContext ctx, Store store) return result; } - private dynamic ToDynamic(DataExportTaskContext ctx, DeliveryTime deliveryTime) + private dynamic ToDynamic(DataExporterContext ctx, DeliveryTime deliveryTime) { if (deliveryTime == null) return null; @@ -419,7 +419,7 @@ private dynamic ToDynamic(DataExportTaskContext ctx, DeliveryTime deliveryTime) return result; } - private void ToDeliveryTime(DataExportTaskContext ctx, dynamic parent, int? deliveryTimeId) + private void ToDeliveryTime(DataExporterContext ctx, dynamic parent, int? deliveryTimeId) { if (ctx.DeliveryTimes != null) { @@ -430,7 +430,7 @@ private void ToDeliveryTime(DataExportTaskContext ctx, dynamic parent, int? deli } } - private dynamic ToDynamic(DataExportTaskContext ctx, QuantityUnit quantityUnit) + private dynamic ToDynamic(DataExporterContext ctx, QuantityUnit quantityUnit) { if (quantityUnit == null) return null; @@ -447,7 +447,7 @@ private dynamic ToDynamic(DataExportTaskContext ctx, QuantityUnit quantityUnit) return result; } - private void ToQuantityUnit(DataExportTaskContext ctx, dynamic parent, int? quantityUnitId) + private void ToQuantityUnit(DataExporterContext ctx, dynamic parent, int? quantityUnitId) { if (ctx.QuantityUnits != null) { @@ -458,26 +458,26 @@ private void ToQuantityUnit(DataExportTaskContext ctx, dynamic parent, int? quan } } - private dynamic ToDynamic(DataExportTaskContext ctx, Picture picture, int thumbPictureSize, int detailsPictureSize) + private dynamic ToDynamic(DataExporterContext ctx, Picture picture, int thumbPictureSize, int detailsPictureSize) { if (picture == null) return null; dynamic result = new DynamicEntity(picture); - result._ThumbImageUrl = _pictureService.GetPictureUrl(picture, thumbPictureSize, false, ctx.Store.Url); - result._ImageUrl = _pictureService.GetPictureUrl(picture, detailsPictureSize, false, ctx.Store.Url); - result._FullSizeImageUrl = _pictureService.GetPictureUrl(picture, 0, false, ctx.Store.Url); + result._ThumbImageUrl = _pictureService.Value.GetPictureUrl(picture, thumbPictureSize, false, ctx.Store.Url); + result._ImageUrl = _pictureService.Value.GetPictureUrl(picture, detailsPictureSize, false, ctx.Store.Url); + result._FullSizeImageUrl = _pictureService.Value.GetPictureUrl(picture, 0, false, ctx.Store.Url); - var relativeUrl = _pictureService.GetPictureUrl(picture); + var relativeUrl = _pictureService.Value.GetPictureUrl(picture); result._FileName = relativeUrl.Substring(relativeUrl.LastIndexOf("/") + 1); - result._ThumbLocalPath = _pictureService.GetThumbLocalPath(picture); + result._ThumbLocalPath = _pictureService.Value.GetThumbLocalPath(picture); return result; } - private dynamic ToDynamic(DataExportTaskContext ctx, ProductVariantAttribute pva) + private dynamic ToDynamic(DataExporterContext ctx, ProductVariantAttribute pva) { if (pva == null) return null; @@ -511,7 +511,7 @@ private dynamic ToDynamic(DataExportTaskContext ctx, ProductVariantAttribute pva return result; } - private dynamic ToDynamic(DataExportTaskContext ctx, ProductVariantAttributeCombination pvac) + private dynamic ToDynamic(DataExporterContext ctx, ProductVariantAttributeCombination pvac) { if (pvac == null) return null; @@ -524,7 +524,7 @@ private dynamic ToDynamic(DataExportTaskContext ctx, ProductVariantAttributeComb return result; } - private dynamic ToDynamic(DataExportTaskContext ctx, Manufacturer manufacturer) + private dynamic ToDynamic(DataExporterContext ctx, Manufacturer manufacturer) { if (manufacturer == null) return null; @@ -550,7 +550,7 @@ private dynamic ToDynamic(DataExportTaskContext ctx, Manufacturer manufacturer) return result; } - private dynamic ToDynamic(DataExportTaskContext ctx, Category category) + private dynamic ToDynamic(DataExporterContext ctx, Category category) { if (category == null) return null; @@ -580,7 +580,7 @@ private dynamic ToDynamic(DataExportTaskContext ctx, Category category) return result; } - private dynamic ToDynamic(DataExportTaskContext ctx, Product product) + private dynamic ToDynamic(DataExporterContext ctx, Product product) { if (product == null) return null; @@ -619,7 +619,7 @@ private dynamic ToDynamic(DataExportTaskContext ctx, Product product) return result; } - private dynamic ToDynamic(DataExportTaskContext ctx, Order order) + private dynamic ToDynamic(DataExporterContext ctx, Order order) { if (order == null) return null; @@ -642,7 +642,7 @@ private dynamic ToDynamic(DataExportTaskContext ctx, Order order) return result; } - private dynamic ToDynamic(DataExportTaskContext ctx, OrderItem orderItem) + private dynamic ToDynamic(DataExporterContext ctx, OrderItem orderItem) { if (orderItem == null) return null; @@ -654,7 +654,7 @@ private dynamic ToDynamic(DataExportTaskContext ctx, OrderItem orderItem) return result; } - private dynamic ToDynamic(DataExportTaskContext ctx, Shipment shipment) + private dynamic ToDynamic(DataExporterContext ctx, Shipment shipment) { if (shipment == null) return null; @@ -673,7 +673,7 @@ private dynamic ToDynamic(DataExportTaskContext ctx, Shipment shipment) return result; } - private dynamic ToDynamic(DataExportTaskContext ctx, Discount discount) + private dynamic ToDynamic(DataExporterContext ctx, Discount discount) { if (discount == null) return null; @@ -683,7 +683,7 @@ private dynamic ToDynamic(DataExportTaskContext ctx, Discount discount) return result; } - private dynamic ToDynamic(DataExportTaskContext ctx, ProductSpecificationAttribute psa) + private dynamic ToDynamic(DataExporterContext ctx, ProductSpecificationAttribute psa) { if (psa == null) return null; @@ -709,7 +709,7 @@ private dynamic ToDynamic(DataExportTaskContext ctx, ProductSpecificationAttribu return result; } - private dynamic ToDynamic(DataExportTaskContext ctx, GenericAttribute genericAttribute) + private dynamic ToDynamic(DataExporterContext ctx, GenericAttribute genericAttribute) { if (genericAttribute == null) return null; @@ -719,7 +719,7 @@ private dynamic ToDynamic(DataExportTaskContext ctx, GenericAttribute genericAtt return result; } - private dynamic ToDynamic(DataExportTaskContext ctx, NewsLetterSubscription subscription) + private dynamic ToDynamic(DataExporterContext ctx, NewsLetterSubscription subscription) { if (subscription == null) return null; @@ -730,13 +730,13 @@ private dynamic ToDynamic(DataExportTaskContext ctx, NewsLetterSubscription subs } - private List Convert(DataExportTaskContext ctx, Product product) + private List Convert(DataExporterContext ctx, Product product) { var result = new List(); var languageId = (ctx.Projection.LanguageId ?? 0); var productTemplate = ctx.ProductTemplates.FirstOrDefault(x => x.Key == product.ProductTemplateId); - var pictureSize = _mediaSettings.ProductDetailsPictureSize; + var pictureSize = _mediaSettings.Value.ProductDetailsPictureSize; if (ctx.Supports(ExportFeatures.CanIncludeMainPicture) && ctx.Projection.PictureSize > 0) pictureSize = ctx.Projection.PictureSize; @@ -762,12 +762,12 @@ private List Convert(DataExportTaskContext ctx, Product product) if (ctx.Categories.Count > 0 && ctx.CategoryPathes.Count > 0) { - dynObject._CategoryPath = _categoryService.GetCategoryPath( + dynObject._CategoryPath = _categoryService.Value.GetCategoryPath( product, null, x => ctx.CategoryPathes.ContainsKey(x) ? ctx.CategoryPathes[x] : null, (id, value) => ctx.CategoryPathes[id] = value, - x => ctx.Categories.ContainsKey(x) ? ctx.Categories[x] : _categoryService.GetCategoryById(x), + x => ctx.Categories.ContainsKey(x) ? ctx.Categories[x] : _categoryService.Value.GetCategoryById(x), productCategories.OrderBy(x => x.DisplayOrder).FirstOrDefault() ); } @@ -782,7 +782,7 @@ private List Convert(DataExportTaskContext ctx, Product product) { dynamic dyn = new DynamicEntity(x); - dyn.Picture = ToDynamic(ctx, x.Picture, _mediaSettings.ProductThumbPictureSize, pictureSize); + dyn.Picture = ToDynamic(ctx, x.Picture, _mediaSettings.Value.ProductThumbPictureSize, pictureSize); return dyn; }) @@ -797,7 +797,7 @@ private List Convert(DataExportTaskContext ctx, Product product) dyn.Manufacturer = ToDynamic(ctx, x.Manufacturer); if (x.Manufacturer != null && x.Manufacturer.PictureId.HasValue) - dyn.Manufacturer.Picture = ToDynamic(ctx, x.Manufacturer.Picture, _mediaSettings.ManufacturerThumbPictureSize, _mediaSettings.ManufacturerThumbPictureSize); + dyn.Manufacturer.Picture = ToDynamic(ctx, x.Manufacturer.Picture, _mediaSettings.Value.ManufacturerThumbPictureSize, _mediaSettings.Value.ManufacturerThumbPictureSize); else dyn.Manufacturer.Picture = null; @@ -814,7 +814,7 @@ private List Convert(DataExportTaskContext ctx, Product product) dyn.Category = ToDynamic(ctx, x.Category); if (x.Category != null && x.Category.PictureId.HasValue) - dyn.Category.Picture = ToDynamic(ctx, x.Category.Picture, _mediaSettings.CategoryThumbPictureSize, _mediaSettings.CategoryThumbPictureSize); + dyn.Category.Picture = ToDynamic(ctx, x.Category.Picture, _mediaSettings.Value.CategoryThumbPictureSize, _mediaSettings.Value.CategoryThumbPictureSize); if (dynObject._CategoryName == null) dynObject._CategoryName = (string)dyn.Category.Name; @@ -839,7 +839,7 @@ private List Convert(DataExportTaskContext ctx, Product product) var assignedPicture = productPictures.FirstOrDefault(y => y.PictureId == pictureId); if (assignedPicture != null && assignedPicture.Picture != null) { - assignedPictures.Add(ToDynamic(ctx, assignedPicture.Picture, _mediaSettings.ProductThumbPictureSize, pictureSize)); + assignedPictures.Add(ToDynamic(ctx, assignedPicture.Picture, _mediaSettings.Value.ProductThumbPictureSize, pictureSize)); } } @@ -934,9 +934,9 @@ private List Convert(DataExportTaskContext ctx, Product product) if (ctx.Supports(ExportFeatures.CanIncludeMainPicture)) { if (productPictures != null && productPictures.Any()) - dynObject._MainPictureUrl = _pictureService.GetPictureUrl(productPictures.First().Picture, ctx.Projection.PictureSize, storeLocation: ctx.Store.Url); + dynObject._MainPictureUrl = _pictureService.Value.GetPictureUrl(productPictures.First().Picture, ctx.Projection.PictureSize, storeLocation: ctx.Store.Url); else - dynObject._MainPictureUrl = _pictureService.GetDefaultPictureUrl(ctx.Projection.PictureSize, storeLocation: ctx.Store.Url); + dynObject._MainPictureUrl = _pictureService.Value.GetDefaultPictureUrl(ctx.Projection.PictureSize, storeLocation: ctx.Store.Url); } #endregion @@ -975,7 +975,7 @@ private List Convert(DataExportTaskContext ctx, Product product) return result; } - private List Convert(DataExportTaskContext ctx, Order order) + private List Convert(DataExporterContext ctx, Order order) { var result = new List(); @@ -1025,8 +1025,8 @@ private List Convert(DataExportTaskContext ctx, Order order) dyn.Product._ProductTemplateViewPath = (productTemplate.Value == null ? "" : productTemplate.Value.ViewPath); - dyn.Product._BasePriceInfo = e.Product.GetBasePriceInfo(_services.Localization, _priceFormatter, _currencyService, _taxService, - _priceCalculationService, ctx.ContextCurrency, decimal.Zero, true); + dyn.Product._BasePriceInfo = e.Product.GetBasePriceInfo(_services.Localization, _priceFormatter.Value, _currencyService.Value, _taxService.Value, + _priceCalculationService.Value, ctx.ContextCurrency, decimal.Zero, true); ToDeliveryTime(ctx, dyn.Product, e.Product.DeliveryTimeId); ToQuantityUnit(ctx, dyn.Product, e.Product.QuantityUnitId); @@ -1044,7 +1044,7 @@ private List Convert(DataExportTaskContext ctx, Order order) return result; } - private List Convert(DataExportTaskContext ctx, Manufacturer manufacturer) + private List Convert(DataExporterContext ctx, Manufacturer manufacturer) { var result = new List(); @@ -1057,7 +1057,7 @@ private List Convert(DataExportTaskContext ctx, Manufacturer manufactur var pictures = ctx.ManufacturerExportContext.Pictures.Load(manufacturer.PictureId.Value); if (pictures.Count > 0) - dynObject.Picture = ToDynamic(ctx, pictures.First(), _mediaSettings.ManufacturerThumbPictureSize, _mediaSettings.ManufacturerThumbPictureSize); + dynObject.Picture = ToDynamic(ctx, pictures.First(), _mediaSettings.Value.ManufacturerThumbPictureSize, _mediaSettings.Value.ManufacturerThumbPictureSize); } dynObject.ProductManufacturers = productManufacturers @@ -1075,7 +1075,7 @@ private List Convert(DataExportTaskContext ctx, Manufacturer manufactur return result; } - private List Convert(DataExportTaskContext ctx, Category category) + private List Convert(DataExporterContext ctx, Category category) { var result = new List(); @@ -1088,7 +1088,7 @@ private List Convert(DataExportTaskContext ctx, Category category) var pictures = ctx.CategoryExportContext.Pictures.Load(category.PictureId.Value); if (pictures.Count > 0) - dynObject.Picture = ToDynamic(ctx, pictures.First(), _mediaSettings.CategoryThumbPictureSize, _mediaSettings.CategoryThumbPictureSize); + dynObject.Picture = ToDynamic(ctx, pictures.First(), _mediaSettings.Value.CategoryThumbPictureSize, _mediaSettings.Value.CategoryThumbPictureSize); } dynObject.ProductCategories = productCategories @@ -1106,7 +1106,7 @@ private List Convert(DataExportTaskContext ctx, Category category) return result; } - private List Convert(DataExportTaskContext ctx, Customer customer) + private List Convert(DataExporterContext ctx, Customer customer) { var result = new List(); @@ -1142,7 +1142,7 @@ private List Convert(DataExportTaskContext ctx, Customer customer) return result; } - private List Convert(DataExportTaskContext ctx, NewsLetterSubscription subscription) + private List Convert(DataExporterContext ctx, NewsLetterSubscription subscription) { var result = new List(); diff --git a/src/Libraries/SmartStore.Services/SmartStore.Services.csproj b/src/Libraries/SmartStore.Services/SmartStore.Services.csproj index 0e67aca232..83fe5c10e4 100644 --- a/src/Libraries/SmartStore.Services/SmartStore.Services.csproj +++ b/src/Libraries/SmartStore.Services/SmartStore.Services.csproj @@ -169,6 +169,7 @@ + From bca184d4728c09f28e475242bd2b251e6d9c66ca Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Wed, 11 Nov 2015 14:40:04 +0100 Subject: [PATCH 016/626] Further IDataExporter implementation --- .../DataExchange/Internal/DataExporter.cs | 184 ++++++++++++------ .../Internal/DataExporterContext.cs | 35 ++-- 2 files changed, 140 insertions(+), 79 deletions(-) diff --git a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporter.cs b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporter.cs index 391b210db6..37d64d5fbb 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporter.cs @@ -29,7 +29,6 @@ using SmartStore.Services.Orders; using SmartStore.Services.Seo; using SmartStore.Services.Shipping; -using SmartStore.Services.Tasks; using SmartStore.Services.Tax; using SmartStore.Utilities; using SmartStore.Utilities.Threading; @@ -158,8 +157,8 @@ private void SetProgress(DataExporterContext ctx, int loadedRecords) { int totalRecords = ctx.RecordsPerStore.Sum(x => x.Value); - if (ctx.Profile.Limit > 0 && totalRecords > ctx.Profile.Limit) - totalRecords = ctx.Profile.Limit; + if (ctx.Request.Profile.Limit > 0 && totalRecords > ctx.Request.Profile.Limit) + totalRecords = ctx.Request.Profile.Limit; ctx.RecordCount = Math.Min(ctx.RecordCount + loadedRecords, totalRecords); @@ -179,15 +178,15 @@ private void SetProgress(DataExporterContext ctx, string message) private IExportDataSegmenterProvider CreateSegmenter(DataExporterContext ctx, int pageIndex = 0) { - var offset = ctx.Profile.Offset + (pageIndex * PageSize); + var offset = ctx.Request.Profile.Offset + (pageIndex * PageSize); - var limit = (ctx.IsPreview ? PageSize : ctx.Profile.Limit); + var limit = (ctx.IsPreview ? PageSize : ctx.Request.Profile.Limit); - var recordsPerSegment = (ctx.IsPreview ? 0 : ctx.Profile.BatchSize); + var recordsPerSegment = (ctx.IsPreview ? 0 : ctx.Request.Profile.BatchSize); - var totalCount = ctx.Profile.Offset + ctx.RecordsPerStore.First(x => x.Key == ctx.Store.Id).Value; + var totalCount = ctx.Request.Profile.Offset + ctx.RecordsPerStore.First(x => x.Key == ctx.Store.Id).Value; - switch (ctx.Provider.Value.EntityType) + switch (ctx.Request.Provider.Value.EntityType) { case ExportEntityType.Product: ctx.ExecuteContext.Segmenter = new ExportDataSegmenter @@ -311,11 +310,11 @@ private bool CallProvider(DataExporterContext ctx, string streamId, string metho { if (method == "Execute") { - ctx.Provider.Value.Execute(ctx.ExecuteContext); + ctx.Request.Provider.Value.Execute(ctx.ExecuteContext); } else if (method == "OnExecuted") { - ctx.Provider.Value.OnExecuted(ctx.ExecuteContext); + ctx.Request.Provider.Value.OnExecuted(ctx.ExecuteContext); } if (ctx.IsFileBasedExport && path.HasValue()) @@ -355,17 +354,17 @@ private bool CallProvider(DataExporterContext ctx, string streamId, string metho private void SendCompletionEmail(DataExporterContext ctx) { - var emailAccount = _emailAccountService.Value.GetEmailAccountById(ctx.Profile.EmailAccountId); + var emailAccount = _emailAccountService.Value.GetEmailAccountById(ctx.Request.Profile.EmailAccountId); var smtpContext = new SmtpContext(emailAccount); var message = new EmailMessage(); var storeInfo = "{0} ({1})".FormatInvariant(ctx.Store.Name, ctx.Store.Url); - message.To.AddRange(ctx.Profile.CompletedEmailAddresses.SplitSafe(",").Where(x => x.IsEmail()).Select(x => new EmailAddress(x))); + message.To.AddRange(ctx.Request.Profile.CompletedEmailAddresses.SplitSafe(",").Where(x => x.IsEmail()).Select(x => new EmailAddress(x))); message.From = new EmailAddress(emailAccount.Email, emailAccount.DisplayName); message.Subject = _services.Localization.GetResource("Admin.DataExchange.Export.CompletedEmail.Subject", ctx.Projection.LanguageId ?? 0) - .FormatInvariant(ctx.Profile.Name); + .FormatInvariant(ctx.Request.Profile.Name); message.Body = _services.Localization.GetResource("Admin.DataExchange.Export.CompletedEmail.Body", ctx.Projection.LanguageId ?? 0) .FormatInvariant(storeInfo); @@ -387,7 +386,7 @@ private IQueryable GetProductQuery(DataExporterContext ctx, int skip, i { OrderBy = ProductSortingEnum.CreatedOn, ProductIds = ctx.EntityIdsSelected, - StoreId = (ctx.Profile.PerStore ? ctx.Store.Id : ctx.Filter.StoreId), + StoreId = (ctx.Request.Profile.PerStore ? ctx.Store.Id : ctx.Filter.StoreId), VisibleIndividuallyOnly = true, PriceMin = ctx.Filter.PriceMinimum, PriceMax = ctx.Filter.PriceMaximum, @@ -454,7 +453,7 @@ private List GetProducts(DataExporterContext ctx, int skip) { OrderBy = ProductSortingEnum.CreatedOn, PageSize = int.MaxValue, - StoreId = (ctx.Profile.PerStore ? ctx.Store.Id : ctx.Filter.StoreId), + StoreId = (ctx.Request.Profile.PerStore ? ctx.Store.Id : ctx.Filter.StoreId), VisibleIndividuallyOnly = false, ParentGroupedProductId = product.Id }; @@ -485,7 +484,7 @@ private List GetProducts(DataExporterContext ctx, int skip) private IQueryable GetOrderQuery(DataExporterContext ctx, int skip, int take) { var query = _orderService.Value.GetOrders( - ctx.Profile.PerStore ? ctx.Store.Id : ctx.Filter.StoreId, + ctx.Request.Profile.PerStore ? ctx.Store.Id : ctx.Filter.StoreId, ctx.Projection.CustomerId ?? 0, ctx.Filter.CreatedFrom.HasValue ? (DateTime?)_dateTimeHelper.Value.ConvertToUtcTime(ctx.Filter.CreatedFrom.Value, _dateTimeHelper.Value.CurrentTimeZone) : null, ctx.Filter.CreatedTo.HasValue ? (DateTime?)_dateTimeHelper.Value.ConvertToUtcTime(ctx.Filter.CreatedTo.Value, _dateTimeHelper.Value.CurrentTimeZone) : null, @@ -536,7 +535,7 @@ private List GetOrders(DataExporterContext ctx, int skip) private IQueryable GetManufacturerQuery(DataExporterContext ctx, int skip, int take) { var showHidden = !ctx.Filter.IsPublished.HasValue; - var storeId = (ctx.Profile.PerStore ? ctx.Store.Id : ctx.Filter.StoreId); + var storeId = (ctx.Request.Profile.PerStore ? ctx.Store.Id : ctx.Filter.StoreId); var query = _manufacturerService.Value.GetManufacturers(showHidden, storeId); @@ -569,7 +568,7 @@ private List GetManufacturers(DataExporterContext ctx, int skip) private IQueryable GetCategoryQuery(DataExporterContext ctx, int skip, int take) { var showHidden = !ctx.Filter.IsPublished.HasValue; - var storeId = (ctx.Profile.PerStore ? ctx.Store.Id : ctx.Filter.StoreId); + var storeId = (ctx.Request.Profile.PerStore ? ctx.Store.Id : ctx.Filter.StoreId); var query = _categoryService.Value.GetCategories(null, showHidden, null, true, storeId); @@ -644,7 +643,7 @@ private List GetCustomers(DataExporterContext ctx, int skip) private IQueryable GetNewsLetterSubscriptionQuery(DataExporterContext ctx, int skip, int take) { - var storeId = (ctx.Profile.PerStore ? ctx.Store.Id : ctx.Filter.StoreId); + var storeId = (ctx.Request.Profile.PerStore ? ctx.Store.Id : ctx.Filter.StoreId); var query = _subscriptionRepository.Value.TableUntracked; @@ -706,7 +705,7 @@ private List Init(DataExporterContext ctx, int? totalRecords = null) ctx.Stores = _services.StoreService.GetAllStores().ToDictionary(x => x.Id, x => x); ctx.Languages = _languageService.Value.GetAllLanguages(true).ToDictionary(x => x.Id, x => x); - if (!ctx.IsPreview && ctx.Profile.PerStore) + if (!ctx.IsPreview && ctx.Request.Profile.PerStore) { result = new List(ctx.Stores.Values.Where(x => x.Id == ctx.Filter.StoreId || ctx.Filter.StoreId == 0)); } @@ -732,25 +731,25 @@ private List Init(DataExporterContext ctx, int? totalRecords = null) } else { - switch (ctx.Provider.Value.EntityType) + switch (ctx.Request.Provider.Value.EntityType) { case ExportEntityType.Product: - totalCount = GetProductQuery(ctx, ctx.Profile.Offset, int.MaxValue).Count(); + totalCount = GetProductQuery(ctx, ctx.Request.Profile.Offset, int.MaxValue).Count(); break; case ExportEntityType.Order: - totalCount = GetOrderQuery(ctx, ctx.Profile.Offset, int.MaxValue).Count(); + totalCount = GetOrderQuery(ctx, ctx.Request.Profile.Offset, int.MaxValue).Count(); break; case ExportEntityType.Manufacturer: - totalCount = GetManufacturerQuery(ctx, ctx.Profile.Offset, int.MaxValue).Count(); + totalCount = GetManufacturerQuery(ctx, ctx.Request.Profile.Offset, int.MaxValue).Count(); break; case ExportEntityType.Category: - totalCount = GetCategoryQuery(ctx, ctx.Profile.Offset, int.MaxValue).Count(); + totalCount = GetCategoryQuery(ctx, ctx.Request.Profile.Offset, int.MaxValue).Count(); break; case ExportEntityType.Customer: - totalCount = GetCustomerQuery(ctx, ctx.Profile.Offset, int.MaxValue).Count(); + totalCount = GetCustomerQuery(ctx, ctx.Request.Profile.Offset, int.MaxValue).Count(); break; case ExportEntityType.NewsLetterSubscription: - totalCount = GetNewsLetterSubscriptionQuery(ctx, ctx.Profile.Offset, int.MaxValue).Count(); + totalCount = GetNewsLetterSubscriptionQuery(ctx, ctx.Request.Profile.Offset, int.MaxValue).Count(); break; } } @@ -775,18 +774,18 @@ private void ExportCoreInner(DataExporterContext ctx, Store store) logHead.AppendLine(); logHead.AppendLine(new string('-', 40)); logHead.AppendLine("SmartStore.NET:\t\tv." + SmartStoreVersion.CurrentFullVersion); - logHead.Append("Export profile:\t\t" + ctx.Profile.Name); - logHead.AppendLine(ctx.Profile.Id == 0 ? " (volatile)" : " (Id {0})".FormatInvariant(ctx.Profile.Id)); + logHead.Append("Export profile:\t\t" + ctx.Request.Profile.Name); + logHead.AppendLine(ctx.Request.Profile.Id == 0 ? " (volatile)" : " (Id {0})".FormatInvariant(ctx.Request.Profile.Id)); - logHead.AppendLine("Export provider:\t{0} ({1})".FormatInvariant(ctx.Provider.Metadata.FriendlyName, ctx.Profile.ProviderSystemName)); + logHead.AppendLine("Export provider:\t{0} ({1})".FormatInvariant(ctx.Request.Provider.Metadata.FriendlyName, ctx.Request.Profile.ProviderSystemName)); - var plugin = ctx.Provider.Metadata.PluginDescriptor; + var plugin = ctx.Request.Provider.Metadata.PluginDescriptor; logHead.Append("Plugin:\t\t\t\t"); logHead.AppendLine(plugin == null ? "".NaIfEmpty() : "{0} ({1}) v.{2}".FormatInvariant(plugin.FriendlyName, plugin.SystemName, plugin.Version.ToString())); - logHead.AppendLine("Entity:\t\t\t\t" + ctx.Provider.Value.EntityType.ToString()); + logHead.AppendLine("Entity:\t\t\t\t" + ctx.Request.Provider.Value.EntityType.ToString()); - var storeInfo = (ctx.Profile.PerStore ? "{0} (Id {1})".FormatInvariant(ctx.Store.Name, ctx.Store.Id) : "All stores"); + var storeInfo = (ctx.Request.Profile.PerStore ? "{0} (Id {1})".FormatInvariant(ctx.Store.Name, ctx.Store.Id) : "All stores"); logHead.Append("Store:\t\t\t\t" + storeInfo); ctx.Log.Information(logHead.ToString()); @@ -796,18 +795,18 @@ private void ExportCoreInner(DataExporterContext ctx, Store store) ctx.ExecuteContext.MaxFileNameLength = _dataExchangeSettings.Value.MaxFileNameLength; - ctx.ExecuteContext.HasPublicDeployment = ctx.Profile.Deployments.Any(x => x.IsPublic && x.DeploymentType == ExportDeploymentType.FileSystem); + ctx.ExecuteContext.HasPublicDeployment = ctx.Request.Profile.Deployments.Any(x => x.IsPublic && x.DeploymentType == ExportDeploymentType.FileSystem); ctx.ExecuteContext.PublicFolderPath = (ctx.ExecuteContext.HasPublicDeployment ? Path.Combine(HttpRuntime.AppDomainAppPath, PublicFolder) : null); - var fileExtension = (ctx.Provider.Value.FileExtension.HasValue() ? ctx.Provider.Value.FileExtension.ToLower().EnsureStartsWith(".") : ""); + var fileExtension = (ctx.Request.Provider.Value.FileExtension.HasValue() ? ctx.Request.Provider.Value.FileExtension.ToLower().EnsureStartsWith(".") : ""); using (var segmenter = CreateSegmenter(ctx)) { if (segmenter == null) { - throw new SmartException("Unsupported entity type '{0}'".FormatInvariant(ctx.Provider.Value.EntityType.ToString())); + throw new SmartException("Unsupported entity type '{0}'".FormatInvariant(ctx.Request.Provider.Value.EntityType.ToString())); } if (segmenter.TotalRecords <= 0) @@ -824,7 +823,7 @@ private void ExportCoreInner(DataExporterContext ctx, Store store) if (ctx.IsFileBasedExport) { - var resolvedPattern = ctx.Profile.ResolveFileNamePattern(ctx.Store, ++fileIndex, ctx.ExecuteContext.MaxFileNameLength); + var resolvedPattern = ctx.Request.Profile.ResolveFileNamePattern(ctx.Store, ++fileIndex, ctx.ExecuteContext.MaxFileNameLength); ctx.ExecuteContext.FileName = resolvedPattern + fileExtension; path = Path.Combine(ctx.ExecuteContext.Folder, ctx.ExecuteContext.FileName); @@ -875,7 +874,7 @@ private void ExportCoreInner(DataExporterContext ctx, Store store) private void ExportCoreOuter(DataExporterContext ctx) { - if (ctx.Profile == null || !ctx.Profile.Enabled) + if (ctx.Request.Profile == null || !ctx.Request.Profile.Enabled) return; FileSystemHelper.Delete(ctx.LogPath); @@ -886,7 +885,7 @@ private void ExportCoreOuter(DataExporterContext ctx) { try { - if (!ctx.Provider.IsValid()) + if (!ctx.Request.Provider.IsValid()) { throw new SmartException("Export aborted because the export provider is not valid"); } @@ -895,12 +894,12 @@ private void ExportCoreOuter(DataExporterContext ctx) ctx.ExecuteContext.Log = logger; ctx.ProgressInfo = T("Admin.DataExchange.Export.ProgressInfo"); - if (ctx.Profile.ProviderConfigData.HasValue()) + if (ctx.Request.Profile.ProviderConfigData.HasValue()) { - var configInfo = ctx.Provider.Value.ConfigurationInfo; + var configInfo = ctx.Request.Provider.Value.ConfigurationInfo; if (configInfo != null) { - ctx.ExecuteContext.ConfigurationData = XmlHelper.Deserialize(ctx.Profile.ProviderConfigData, configInfo.ModelType); + ctx.ExecuteContext.ConfigurationData = XmlHelper.Deserialize(ctx.Request.Profile.ProviderConfigData, configInfo.ModelType); } } @@ -911,18 +910,18 @@ private void ExportCoreOuter(DataExporterContext ctx) ctx.QuantityUnits = _quantityUnitService.Value.GetAllQuantityUnits().ToDictionary(x => x.Id); ctx.ProductTemplates = _productTemplateService.Value.GetAllProductTemplates().ToDictionary(x => x.Id); - if (ctx.Provider.Value.EntityType == ExportEntityType.Product) + if (ctx.Request.Provider.Value.EntityType == ExportEntityType.Product) { var allCategories = _categoryService.Value.GetAllCategories(showHidden: true, applyNavigationFilters: false); ctx.Categories = allCategories.ToDictionary(x => x.Id); } - if (ctx.Provider.Value.EntityType == ExportEntityType.Order) + if (ctx.Request.Provider.Value.EntityType == ExportEntityType.Order) { ctx.Countries = _countryService.Value.GetAllCountries(true).ToDictionary(x => x.Id, x => x); } - if (ctx.Provider.Value.EntityType == ExportEntityType.Customer) + if (ctx.Request.Provider.Value.EntityType == ExportEntityType.Customer) { var subscriptionEmails = _subscriptionRepository.Value.TableUntracked .Where(x => x.Active) @@ -946,7 +945,7 @@ private void ExportCoreOuter(DataExporterContext ctx) { if (ctx.IsFileBasedExport) { - if (ctx.Profile.CreateZipArchive || ctx.Profile.Deployments.Any(x => x.Enabled && x.CreateZip)) + if (ctx.Request.Profile.CreateZipArchive || ctx.Request.Profile.Deployments.Any(x => x.Enabled && x.CreateZip)) { ZipFile.CreateFromDirectory(ctx.FolderContent, ctx.ZipPath, CompressionLevel.Fastest, true); } @@ -954,7 +953,7 @@ private void ExportCoreOuter(DataExporterContext ctx) SetProgress(ctx, T("Common.Deployment")); // TODO: deployment - //foreach (var deployment in ctx.Profile.Deployments.OrderBy(x => x.DeploymentTypeId).Where(x => x.Enabled)) + //foreach (var deployment in ctx.Request.Profile.Deployments.OrderBy(x => x.DeploymentTypeId).Where(x => x.Enabled)) //{ // try // { @@ -982,7 +981,7 @@ private void ExportCoreOuter(DataExporterContext ctx) //} } - if (ctx.Profile.EmailAccountId != 0 && ctx.Profile.CompletedEmailAddresses.HasValue()) + if (ctx.Request.Profile.EmailAccountId != 0 && ctx.Request.Profile.CompletedEmailAddresses.HasValue()) { SendCompletionEmail(ctx); } @@ -997,18 +996,18 @@ private void ExportCoreOuter(DataExporterContext ctx) { try { - if (!ctx.IsPreview && ctx.Profile.Id != 0) + if (!ctx.IsPreview && ctx.Request.Profile.Id != 0) { - ctx.Profile.ResultInfo = XmlHelper.Serialize(ctx.Result); + ctx.Request.Profile.ResultInfo = XmlHelper.Serialize(ctx.Result); - _exportProfileService.Value.UpdateExportProfile(ctx.Profile); + _exportProfileService.Value.UpdateExportProfile(ctx.Request.Profile); } } catch { } try { - if (ctx.IsFileBasedExport && ctx.ExecuteContext.Abort != ExportAbortion.Hard && ctx.Profile.Cleanup) + if (ctx.IsFileBasedExport && ctx.ExecuteContext.Abort != ExportAbortion.Hard && ctx.Request.Profile.Cleanup) { FileSystemHelper.ClearDirectory(ctx.FolderContent, false); } @@ -1059,17 +1058,92 @@ public static int PageSize public DataExportResult Export(DataExportRequest request, CancellationToken cancellationToken) { - return null; + var ctx = new DataExporterContext(request, cancellationToken); + + ExportCoreOuter(ctx); + + if (ctx.Result != null && ctx.Result.Succeeded && ctx.Result.Files.Count > 0) + { + string prefix = null; + string suffix = null; + var extension = Path.GetExtension(ctx.Result.Files.First().FileName); + var selectedEntityCount = (request.EntitiesToExport == null ? 0 : request.EntitiesToExport.Count()); + + if (request.Provider.Value.EntityType == ExportEntityType.Product) + prefix = T("Admin.Catalog.Products"); + else if (request.Provider.Value.EntityType == ExportEntityType.Order) + prefix = T("Admin.Orders"); + else if (request.Provider.Value.EntityType == ExportEntityType.Category) + prefix = T("Admin.Catalog.Categories"); + else if (request.Provider.Value.EntityType == ExportEntityType.Manufacturer) + prefix = T("Admin.Catalog.Manufacturers"); + else if (request.Provider.Value.EntityType == ExportEntityType.Customer) + prefix = T("Admin.Customers"); + else if (request.Provider.Value.EntityType == ExportEntityType.NewsLetterSubscription) + prefix = T("Admin.Promotions.NewsLetterSubscriptions"); + else + prefix = request.Provider.Value.EntityType.ToString(); + + if (selectedEntityCount == 0) + suffix = T("Common.All"); + else + suffix = (selectedEntityCount == 1 ? request.EntitiesToExport.First().ToString() : T("Admin.Common.Selected").Text); + + ctx.Result.DownloadFileName = string.Concat(prefix, "-", suffix).ToLower().ToValidFileName() + extension; + } + + return ctx.Result; } public IList Preview(DataExportRequest request) { - return null; + var pageIndex = (request.CustomData.ContainsKey("PageIndex") ? (int)request.CustomData["PageIndex"] : 0); + var totalRecords = (request.CustomData.ContainsKey("TotalRecords") ? (int)request.CustomData["TotalRecords"] : 0); + + var result = new List(); + var cancellation = new CancellationTokenSource(TimeSpan.FromMinutes(5.0)); + + var ctx = new DataExporterContext(request, cancellation.Token, null, true); + + var unused = Init(ctx, totalRecords); + + using (var segmenter = CreateSegmenter(ctx, pageIndex)) + { + if (segmenter == null) + { + throw new SmartException("Unsupported entity type '{0}'".FormatInvariant(ctx.Request.Provider.Value.EntityType.ToString())); + } + + while (segmenter.HasData) + { + segmenter.RecordPerSegmentCount = 0; + + while (segmenter.ReadNextSegment()) + { + result.AddRange(segmenter.CurrentSegment); + } + } + } + + if (ctx.Result.LastError.HasValue()) + { + _services.Notifier.Error(ctx.Result.LastError); + } + + return result; } public long GetDataCount(DataExportRequest request) { - return 0; + var cancellation = new CancellationTokenSource(TimeSpan.FromMinutes(5.0)); + + var ctx = new DataExporterContext(request, cancellation.Token, null, true); + + var unused = Init(ctx); + + var totalCount = ctx.RecordsPerStore.First().Value; + + return totalCount; } } } diff --git a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporterContext.cs b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporterContext.cs index cb95e67f23..2ae610ca6d 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporterContext.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporterContext.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading; @@ -12,7 +11,6 @@ using SmartStore.Core.Domain.Localization; using SmartStore.Core.Domain.Stores; using SmartStore.Core.Logging; -using SmartStore.Core.Plugins; using SmartStore.Utilities; namespace SmartStore.Services.DataExchange.Internal @@ -28,21 +26,17 @@ internal class DataExporterContext public DataExporterContext( DataExportRequest request, CancellationToken cancellationToken, - ExportProfile profile, - Provider provider, string selectedIds = null, - Action previewData = null) + bool isPreview = false) { Request = request; CancellationToken = cancellationToken; - Profile = profile; - Provider = provider; - Filter = XmlHelper.Deserialize(profile.Filtering); - Projection = XmlHelper.Deserialize(profile.Projection); + Filter = XmlHelper.Deserialize(request.Profile.Filtering); + Projection = XmlHelper.Deserialize(request.Profile.Projection); EntityIdsSelected = selectedIds.SplitSafe(",").Select(x => x.ToInt()).ToList(); - PreviewData = previewData; + IsPreview = isPreview; - FolderContent = FileSystemHelper.TempDir(@"Profile\Export\{0}\Content".FormatInvariant(profile.FolderName)); + FolderContent = FileSystemHelper.TempDir(@"Profile\Export\{0}\Content".FormatInvariant(request.Profile.FolderName)); FolderRoot = System.IO.Directory.GetParent(FolderContent).FullName; Categories = new Dictionary(); @@ -60,7 +54,7 @@ public DataExporterContext( }; ExecuteContext = new ExportExecuteContext(Result, CancellationToken, FolderContent); - ExecuteContext.Projection = XmlHelper.Deserialize(profile.Projection); + ExecuteContext.Projection = XmlHelper.Deserialize(request.Profile.Projection); } public List EntityIdsSelected { get; private set; } @@ -71,20 +65,13 @@ public DataExporterContext( public string ProgressInfo { get; set; } public IQueryable QueryProducts { get; set; } - public Action PreviewData { get; private set; } - public bool IsPreview - { - get { return PreviewData != null; } - } - public DataExportRequest Request { get; private set; } public CancellationToken CancellationToken { get; private set; } - public ExportProfile Profile { get; private set; } - public Provider Provider { get; private set; } + public bool IsPreview { get; private set; } public bool Supports(ExportFeatures feature) { - return (!IsPreview && Provider.Metadata.ExportFeatures.HasFlag(feature)); + return (!IsPreview && Request.Provider.Metadata.ExportFeatures.HasFlag(feature)); } public ExportFilter Filter { get; private set; } @@ -100,7 +87,7 @@ public bool Supports(ExportFeatures feature) public string FolderContent { get; private set; } public string ZipName { - get { return Profile.FolderName + ".zip"; } + get { return Request.Profile.FolderName + ".zip"; } } public string ZipPath { @@ -113,7 +100,7 @@ public string LogPath public bool IsFileBasedExport { - get { return Provider == null || Provider.Value == null || Provider.Value.FileExtension.HasValue(); } + get { return Request.Provider == null || Request.Provider.Value == null || Request.Provider.Value.FileExtension.HasValue(); } } public string[] GetDeploymentFiles(ExportDeployment deployment) { From fadd6dda9cf31a871c27289ef1f2b78951c6076a Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Wed, 11 Nov 2015 17:26:08 +0100 Subject: [PATCH 017/626] ExportController using DataExporter --- .../DataExchange/ExportProfileService.cs | 3 +- .../DataExchange/IDataExporter.cs | 5 +- .../DataExchange/Internal/DataExportTask.cs | 1 + .../DataExchange/Internal/DataExporter.cs | 13 +-- .../DependencyRegistrar.cs | 4 +- .../Controllers/ExportController.cs | 87 ++++++++++--------- 6 files changed, 61 insertions(+), 52 deletions(-) diff --git a/src/Libraries/SmartStore.Services/DataExchange/ExportProfileService.cs b/src/Libraries/SmartStore.Services/DataExchange/ExportProfileService.cs index 1651171aa2..414e5c073a 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/ExportProfileService.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/ExportProfileService.cs @@ -10,6 +10,7 @@ using SmartStore.Core.Events; using SmartStore.Core.Plugins; using SmartStore.Services.DataExchange.ExportTask; +using SmartStore.Services.DataExchange.Internal; using SmartStore.Services.Localization; using SmartStore.Services.Tasks; using SmartStore.Utilities; @@ -91,7 +92,7 @@ public virtual ExportProfile InsertExportProfile(Provider provi task = new ScheduleTask { CronExpression = "0 */6 * * *", // every six hours - Type = (new ExportProfileTask()).GetType().AssemblyQualifiedNameWithoutVersion(), + Type = typeof(DataExportTask).AssemblyQualifiedNameWithoutVersion(), Enabled = false, StopOnError = false, IsHidden = true diff --git a/src/Libraries/SmartStore.Services/DataExchange/IDataExporter.cs b/src/Libraries/SmartStore.Services/DataExchange/IDataExporter.cs index 4a96e5c515..843a15351e 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/IDataExporter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/IDataExporter.cs @@ -13,12 +13,9 @@ public interface IDataExporter { DataExportResult Export(DataExportRequest request, CancellationToken cancellationToken); - // Handle model conversion for grid in backend's controller IList Preview(DataExportRequest request); - // useful for decision making whether export should - // be processed sync or async - long GetDataCount(DataExportRequest request); + int GetDataCount(DataExportRequest request); } diff --git a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExportTask.cs b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExportTask.cs index b1e3d31f54..33b2eb1e2a 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExportTask.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExportTask.cs @@ -4,6 +4,7 @@ namespace SmartStore.Services.DataExchange.Internal { + // note: namespace persisted in ScheduleTask.Type public partial class DataExportTask : ITask { private readonly IDataExporter _exporter; diff --git a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporter.cs b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporter.cs index 37d64d5fbb..faccb9748f 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporter.cs @@ -903,8 +903,9 @@ private void ExportCoreOuter(DataExporterContext ctx) } } - // TODO: lazyLoading: false. It requires IDbContextExtensions::Load/QueryFor for properties internally mapped by EF - using (var scope = new DbContextScope(_services.DbContext, autoDetectChanges: false, proxyCreation: false, validateOnSave: false, forceNoTracking: true)) + // TODO: lazyLoading: false, proxyCreation: false possible? how to identify all properties of all data levels of all entities + // that require manual resolving for now and for future? fragile, susceptible to faults (e.g. price calculation)... + using (var scope = new DbContextScope(_services.DbContext, autoDetectChanges: false, proxyCreation: true, validateOnSave: false, forceNoTracking: true)) { ctx.DeliveryTimes = _deliveryTimeService.Value.GetAllDeliveryTimes().ToDictionary(x => x.Id); ctx.QuantityUnits = _quantityUnitService.Value.GetAllQuantityUnits().ToDictionary(x => x.Id); @@ -1100,7 +1101,7 @@ public IList Preview(DataExportRequest request) var pageIndex = (request.CustomData.ContainsKey("PageIndex") ? (int)request.CustomData["PageIndex"] : 0); var totalRecords = (request.CustomData.ContainsKey("TotalRecords") ? (int)request.CustomData["TotalRecords"] : 0); - var result = new List(); + var resultData = new List(); var cancellation = new CancellationTokenSource(TimeSpan.FromMinutes(5.0)); var ctx = new DataExporterContext(request, cancellation.Token, null, true); @@ -1120,7 +1121,7 @@ public IList Preview(DataExportRequest request) while (segmenter.ReadNextSegment()) { - result.AddRange(segmenter.CurrentSegment); + resultData.AddRange(segmenter.CurrentSegment); } } } @@ -1130,10 +1131,10 @@ public IList Preview(DataExportRequest request) _services.Notifier.Error(ctx.Result.LastError); } - return result; + return resultData; } - public long GetDataCount(DataExportRequest request) + public int GetDataCount(DataExportRequest request) { var cancellation = new CancellationTokenSource(TimeSpan.FromMinutes(5.0)); diff --git a/src/Presentation/SmartStore.Web.Framework/DependencyRegistrar.cs b/src/Presentation/SmartStore.Web.Framework/DependencyRegistrar.cs index 7eea57921e..574f649606 100644 --- a/src/Presentation/SmartStore.Web.Framework/DependencyRegistrar.cs +++ b/src/Presentation/SmartStore.Web.Framework/DependencyRegistrar.cs @@ -76,6 +76,7 @@ using Module = Autofac.Module; using SmartStore.Core.Domain.DataExchange; using SmartStore.Utilities.Reflection; +using SmartStore.Services.DataExchange.Internal; namespace SmartStore.Web.Framework { @@ -223,8 +224,9 @@ public virtual void Register(ContainerBuilder builder, ITypeFinder typeFinder, b builder.RegisterType().As().InstancePerRequest(); builder.RegisterType().As().InstancePerRequest(); + builder.RegisterType().As().InstancePerRequest(); - builder.RegisterType().As().InstancePerRequest(); + builder.RegisterType().As().InstancePerRequest(); builder.RegisterType().As().InstancePerRequest(); builder.RegisterType().As().InstancePerRequest(); diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs index e53c712192..55ac7330ac 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs @@ -2,11 +2,8 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Net.Mime; -using System.Text; using System.Web; using System.Web.Mvc; -using Autofac; using SmartStore.Admin.Extensions; using SmartStore.Admin.Models.DataExchange; using SmartStore.Core; @@ -21,12 +18,13 @@ using SmartStore.Services.Catalog; using SmartStore.Services.Customers; using SmartStore.Services.DataExchange; -using SmartStore.Services.DataExchange.ExportTask; +using SmartStore.Services.DataExchange.Internal; using SmartStore.Services.Directory; using SmartStore.Services.Helpers; using SmartStore.Services.Localization; using SmartStore.Services.Messages; using SmartStore.Services.Security; +using SmartStore.Services.Tasks; using SmartStore.Web.Framework; using SmartStore.Web.Framework.Controllers; using SmartStore.Web.Framework.Plugins; @@ -48,9 +46,10 @@ public class ExportController : AdminControllerBase private readonly ILanguageService _languageService; private readonly ICurrencyService _currencyService; private readonly IEmailAccountService _emailAccountService; - private readonly IComponentContext _componentContext; private readonly IDateTimeHelper _dateTimeHelper; private readonly DataExchangeSettings _dataExchangeSettings; + private readonly ITaskScheduler _taskScheduler; + private readonly IDataExporter _dataExporter; public ExportController( ICommonServices services, @@ -63,9 +62,10 @@ public ExportController( ILanguageService languageService, ICurrencyService currencyService, IEmailAccountService emailAccountService, - IComponentContext componentContext, IDateTimeHelper dateTimeHelper, - DataExchangeSettings dataExchangeSettings) + DataExchangeSettings dataExchangeSettings, + ITaskScheduler taskScheduler, + IDataExporter dataExporter) { _services = services; _exportService = exportService; @@ -77,9 +77,10 @@ public ExportController( _languageService = languageService; _currencyService = currencyService; _emailAccountService = emailAccountService; - _componentContext = componentContext; _dateTimeHelper = dateTimeHelper; _dataExchangeSettings = dataExchangeSettings; + _taskScheduler = taskScheduler; + _dataExporter = dataExporter; } #region Utilities @@ -245,7 +246,7 @@ private void PrepareProfileModelForEdit(ExportProfileModel model, ExportProfile { try { - var publicFolder = Path.Combine(HttpRuntime.AppDomainAppPath, ExportProfileTask.PublicFolder); + var publicFolder = Path.Combine(HttpRuntime.AppDomainAppPath, DataExporter.PublicFolder); var resultInfo = XmlHelper.Deserialize(profile.ResultInfo); if (resultInfo != null && resultInfo.Files != null) @@ -261,7 +262,7 @@ private void PrepareProfileModelForEdit(ExportProfileModel model, ExportProfile StoreId = store.Id, StoreName = store.Name, FileName = fileInfo.FileName, - FileUrl = string.Concat(store.Url.EnsureEndsWith("/"), ExportProfileTask.PublicFolder.EnsureEndsWith("/"), fileInfo.FileName) + FileUrl = string.Concat(store.Url.EnsureEndsWith("/"), DataExporter.PublicFolder.EnsureEndsWith("/"), fileInfo.FileName) }); } } @@ -722,15 +723,15 @@ public ActionResult Preview(int id) var provider = _exportService.LoadProvider(profile.ProviderSystemName); - var task = new ExportProfileTask(); - var totalRecords = task.GetRecordCount(profile, provider, _componentContext); + var request = new DataExportRequest(profile, provider); + var totalRecords = _dataExporter.GetDataCount(request); var model = new ExportPreviewModel { Id = profile.Id, Name = profile.Name, ThumbnailUrl = GetThumbnailUrl(provider), - GridPageSize = ExportProfileTask.PageSize, + GridPageSize = DataExporter.PageSize, EntityType = provider.Value.EntityType, TotalRecords = totalRecords, LogFileExists = System.IO.File.Exists(profile.GetExportLogFilePath()) @@ -751,25 +752,30 @@ public ActionResult PreviewList(GridCommand command, int id, int totalRecords) { var productModel = new List(); var orderModel = new List(); - var task = new ExportProfileTask(); - Action previewData = x => + var request = new DataExportRequest(profile, provider); + request.CustomData.Add("PageIndex", command.Page - 1); + request.CustomData.Add("TotalRecords", totalRecords); + + var data = _dataExporter.Preview(request); + + foreach (dynamic item in data) { if (provider.Value.EntityType == ExportEntityType.Product) { - var product = x.Entity as Product; + var product = item.Entity as Product; var pm = new ExportPreviewProductModel { - Id = x.Id, - ProductTypeId = x.ProductTypeId, + Id = product.Id, + ProductTypeId = product.ProductTypeId, ProductTypeName = product.GetProductTypeLabel(_services.Localization), ProductTypeLabelHint = product.ProductTypeLabelHint, - Name = x.Name, - Sku = x.Sku, - Price = x.Price, - Published = x.Published, - StockQuantity = x.StockQuantity, - AdminComment = x.AdminComment + Name = item.Name, + Sku = item.Sku, + Price = item.Price, + Published = product.Published, + StockQuantity = product.StockQuantity, + AdminComment = item.AdminComment }; productModel.Add(pm); @@ -778,23 +784,21 @@ public ActionResult PreviewList(GridCommand command, int id, int totalRecords) { var om = new ExportPreviewOrderModel { - Id = x.Id, - HasNewPaymentNotification = x.HasNewPaymentNotification, - OrderNumber = x.OrderNumber, - OrderStatus = x.OrderStatus, - PaymentStatus = x.PaymentStatus, - ShippingStatus = x.ShippingStatus, - CustomerEmail = x.Customer.Email, - StoreName = (x.Store == null ? "".NaIfEmpty() : x.Store.Name), - CreatedOn = _dateTimeHelper.ConvertToUserTime(x.CreatedOnUtc, DateTimeKind.Utc), - OrderTotal = x.OrderTotal + Id = item.Id, + HasNewPaymentNotification = item.HasNewPaymentNotification, + OrderNumber = item.OrderNumber, + OrderStatus = item.OrderStatus, + PaymentStatus = item.PaymentStatus, + ShippingStatus = item.ShippingStatus, + CustomerEmail = item.Customer.Email, + StoreName = (item.Store == null ? "".NaIfEmpty() : item.Store.Name), + CreatedOn = _dateTimeHelper.ConvertToUserTime(item.CreatedOnUtc, DateTimeKind.Utc), + OrderTotal = item.OrderTotal }; orderModel.Add(om); } - }; - - task.Preview(profile, provider, _componentContext, command.Page - 1, totalRecords, previewData); + } var normalizedTotal = totalRecords; @@ -831,12 +835,15 @@ public ActionResult Execute(int id, string selectedIds, bool exportAll) if (profile == null) return RedirectToAction("List"); + // TODO: profile.CacheSelectedEntityIds(selectedIds); - var returnUrl = Url.Action("List", "Export", new { area = "admin" }); + _taskScheduler.RunSingleTask(profile.SchedulingTaskId); - return RedirectToAction("RunJob", "ScheduleTask", new { area = "admin", id = profile.SchedulingTaskId, returnUrl = returnUrl }); - } + NotifyInfo(T("Admin.System.ScheduleTasks.RunNow.Progress")); + + return RedirectToAction("List"); + } [ChildActionOnly] public ActionResult InfoProfile(string systemName, string returnUrl) From e178bf51efcb3636833c6e7376dbfb9068936bbe Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Wed, 11 Nov 2015 19:51:50 +0100 Subject: [PATCH 018/626] Export of selected entities using task parameter instead of HTTP runtime cache --- .../Collections/Querystring.cs | 11 ++++---- .../201509150931528_ExportFramework2.cs | 4 +++ .../DataExchange/ExportExtensions.cs | 28 ------------------- .../ExportTask/ExportProfileTask.cs | 2 +- .../DataExchange/Internal/DataExportTask.cs | 11 ++------ .../DataExchange/Internal/DataExporter.cs | 12 ++++++-- .../Internal/DataExporterContext.cs | 3 +- .../Tasks/TaskScheduler.cs | 2 +- .../Controllers/ExportController.cs | 13 ++++++--- .../Administration/Views/Export/List.cshtml | 1 - .../Views/Export/Preview.cshtml | 8 ++++-- 11 files changed, 40 insertions(+), 55 deletions(-) diff --git a/src/Libraries/SmartStore.Core/Collections/Querystring.cs b/src/Libraries/SmartStore.Core/Collections/Querystring.cs index 76606ef24d..e430e4ccb2 100644 --- a/src/Libraries/SmartStore.Core/Collections/Querystring.cs +++ b/src/Libraries/SmartStore.Core/Collections/Querystring.cs @@ -45,22 +45,23 @@ public static string ExtractQuerystring(string s) /// /// the string to parse /// the QueryString object - public QueryString FillFromString(string s) + public QueryString FillFromString(string s, bool urlDecode = false) { base.Clear(); if (string.IsNullOrEmpty(s)) { return this; } + foreach (string keyValuePair in ExtractQuerystring(s).Split('&')) { if (string.IsNullOrEmpty(keyValuePair)) { continue; } + string[] split = keyValuePair.Split('='); - base.Add(split[0], - split.Length == 2 ? split[1] : ""); + base.Add(split[0], split.Length == 2 ? (urlDecode ? HttpUtility.UrlDecode(split[1]) : split[1]) : ""); } return this; } @@ -73,7 +74,7 @@ public QueryString FromCurrent() { if (HttpContext.Current != null) { - return FillFromString(HttpContext.Current.Request.QueryString.ToString()); + return FillFromString(HttpContext.Current.Request.QueryString.ToString(), true); } base.Clear(); return this; @@ -182,7 +183,7 @@ public override string ToString() { if (!string.IsNullOrEmpty(base.Keys[i])) { - foreach (string val in base[base.Keys[i]].Split(',')) + foreach (string val in base[base.Keys[i]].EmptyNull().Split(',')) { builder.Append((builder.Length == 0) ? "?" : "&").Append( HttpUtility.UrlEncode(base.Keys[i])).Append("=").Append(val); diff --git a/src/Libraries/SmartStore.Data/Migrations/201509150931528_ExportFramework2.cs b/src/Libraries/SmartStore.Data/Migrations/201509150931528_ExportFramework2.cs index 819cb147ae..b32ed81653 100644 --- a/src/Libraries/SmartStore.Data/Migrations/201509150931528_ExportFramework2.cs +++ b/src/Libraries/SmartStore.Data/Migrations/201509150931528_ExportFramework2.cs @@ -56,6 +56,10 @@ public void MigrateLocaleResources(LocaleResourcesBuilder builder) "Cannot load the provider {0}.", "Der Provider {0} konnte nicht geladen werden."); + builder.AddOrUpdate("Admin.Common.NoEntriesSelected", + "No entries have been selected.", + "Es wurden keine Eintrge ausgewhlt."); + builder.AddOrUpdate("ActivityLog.EditPaymentMethod", "Edited payment method '{0}' ({1})", "Zahlungsart '{0}' ({1}) bearbeitet"); diff --git a/src/Libraries/SmartStore.Services/DataExchange/ExportExtensions.cs b/src/Libraries/SmartStore.Services/DataExchange/ExportExtensions.cs index 8a0cdc959d..cf86f0d411 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/ExportExtensions.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/ExportExtensions.cs @@ -2,8 +2,6 @@ using System.Globalization; using System.IO; using System.Text; -using System.Web; -using System.Web.Caching; using SmartStore.Core.Domain; using SmartStore.Core.Domain.Stores; using SmartStore.Core.Plugins; @@ -96,31 +94,5 @@ public static string ResolveFileNamePattern(this ExportProfile profile, Store st return result; } - - /// - /// Gets the cache key for selected entity identifiers - /// - /// Export profile - /// Cache key for selected entity identifiers - public static string GetSelectedEntityIdsCacheKey(this ExportProfile profile) - { - // do not use profile.Id because it can be 0 - return "ExportProfile_SelectedEntityIds_" + profile.ProviderSystemName; - } - - /// - /// Caches selected entity identifiers to be considered during following export - /// - /// Export profile - /// Comma separated entity identifiers - public static void CacheSelectedEntityIds(this ExportProfile profile, string selectedIds) - { - var selectedIdsCacheKey = profile.GetSelectedEntityIdsCacheKey(); - - if (selectedIds.HasValue()) - HttpRuntime.Cache.Add(selectedIdsCacheKey, selectedIds, null, DateTime.UtcNow.AddMinutes(5), Cache.NoSlidingExpiration, CacheItemPriority.Normal, null); - else - HttpRuntime.Cache.Remove(selectedIdsCacheKey); - } } } diff --git a/src/Libraries/SmartStore.Services/DataExchange/ExportTask/ExportProfileTask.cs b/src/Libraries/SmartStore.Services/DataExchange/ExportTask/ExportProfileTask.cs index 3bc601bedf..95f276a993 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/ExportTask/ExportProfileTask.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/ExportTask/ExportProfileTask.cs @@ -2872,7 +2872,7 @@ public void Execute(TaskExecutionContext taskContext) var profileId = taskContext.ScheduleTask.Alias.ToInt(); var profile = _exportProfileService.Value.GetExportProfileById(profileId); - var selectedIdsCacheKey = profile.GetSelectedEntityIdsCacheKey(); + var selectedIdsCacheKey = "ExportProfile_SelectedEntityIds_" + profile.ProviderSystemName; var selectedEntityIds = HttpRuntime.Cache[selectedIdsCacheKey] as string; var provider = _exportProfileService.Value.LoadProvider(profile.ProviderSystemName); diff --git a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExportTask.cs b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExportTask.cs index 33b2eb1e2a..ab5d8e40c5 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExportTask.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExportTask.cs @@ -27,11 +27,6 @@ public void Execute(TaskExecutionContext ctx) var profileId = ctx.ScheduleTask.Alias.ToInt(); var profile = _exportProfileService.GetExportProfileById(profileId); - // TODO: find a better way to transmit selected entity ids (e.g. new TaskExecutionContext.Parameters property) - var selectedIdsCacheKey = profile.GetSelectedEntityIdsCacheKey(); - var selectedEntityIds = HttpRuntime.Cache[selectedIdsCacheKey] as string; - HttpRuntime.Cache.Remove(selectedIdsCacheKey); - // load provider var provider = _exportProfileService.LoadProvider(profile.ProviderSystemName); if (provider == null) @@ -50,10 +45,10 @@ public void Execute(TaskExecutionContext ctx) ctx.SetProgress(null, msg, true); }; - if (selectedEntityIds.HasValue()) + if (ctx.Parameters.ContainsKey("SelectedIds")) { - request.EntitiesToExport = selectedEntityIds.ToIntArray(); - } + request.EntitiesToExport = ctx.Parameters["SelectedIds"].ToIntArray(); + } // process! _exporter.Export(request, ctx.CancellationToken); diff --git a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporter.cs b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporter.cs index faccb9748f..cc263c1b5b 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporter.cs @@ -1061,6 +1061,11 @@ public DataExportResult Export(DataExportRequest request, CancellationToken canc { var ctx = new DataExporterContext(request, cancellationToken); + if (request.EntitiesToExport != null) + { + ctx.EntityIdsSelected.AddRange(request.EntitiesToExport); + } + ExportCoreOuter(ctx); if (ctx.Result != null && ctx.Result.Succeeded && ctx.Result.Files.Count > 0) @@ -1068,7 +1073,6 @@ public DataExportResult Export(DataExportRequest request, CancellationToken canc string prefix = null; string suffix = null; var extension = Path.GetExtension(ctx.Result.Files.First().FileName); - var selectedEntityCount = (request.EntitiesToExport == null ? 0 : request.EntitiesToExport.Count()); if (request.Provider.Value.EntityType == ExportEntityType.Product) prefix = T("Admin.Catalog.Products"); @@ -1085,6 +1089,8 @@ public DataExportResult Export(DataExportRequest request, CancellationToken canc else prefix = request.Provider.Value.EntityType.ToString(); + var selectedEntityCount = (request.EntitiesToExport == null ? 0 : request.EntitiesToExport.Count()); + if (selectedEntityCount == 0) suffix = T("Common.All"); else @@ -1104,7 +1110,7 @@ public IList Preview(DataExportRequest request) var resultData = new List(); var cancellation = new CancellationTokenSource(TimeSpan.FromMinutes(5.0)); - var ctx = new DataExporterContext(request, cancellation.Token, null, true); + var ctx = new DataExporterContext(request, cancellation.Token, true); var unused = Init(ctx, totalRecords); @@ -1138,7 +1144,7 @@ public int GetDataCount(DataExportRequest request) { var cancellation = new CancellationTokenSource(TimeSpan.FromMinutes(5.0)); - var ctx = new DataExporterContext(request, cancellation.Token, null, true); + var ctx = new DataExporterContext(request, cancellation.Token, true); var unused = Init(ctx); diff --git a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporterContext.cs b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporterContext.cs index 2ae610ca6d..b12b3a1bdb 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporterContext.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporterContext.cs @@ -26,19 +26,18 @@ internal class DataExporterContext public DataExporterContext( DataExportRequest request, CancellationToken cancellationToken, - string selectedIds = null, bool isPreview = false) { Request = request; CancellationToken = cancellationToken; Filter = XmlHelper.Deserialize(request.Profile.Filtering); Projection = XmlHelper.Deserialize(request.Profile.Projection); - EntityIdsSelected = selectedIds.SplitSafe(",").Select(x => x.ToInt()).ToList(); IsPreview = isPreview; FolderContent = FileSystemHelper.TempDir(@"Profile\Export\{0}\Content".FormatInvariant(request.Profile.FolderName)); FolderRoot = System.IO.Directory.GetParent(FolderContent).FullName; + EntityIdsSelected = new List(); Categories = new Dictionary(); CategoryPathes = new Dictionary(); Countries = new Dictionary(); diff --git a/src/Libraries/SmartStore.Services/Tasks/TaskScheduler.cs b/src/Libraries/SmartStore.Services/Tasks/TaskScheduler.cs index 3ff2e5e04f..22cecb7046 100644 --- a/src/Libraries/SmartStore.Services/Tasks/TaskScheduler.cs +++ b/src/Libraries/SmartStore.Services/Tasks/TaskScheduler.cs @@ -113,7 +113,7 @@ public void RunSingleTask(int scheduleTaskId, IDictionary taskPa query = qs.ToString(); } - CallEndpoint(_baseUrl + "/Execute/{0}{1}".FormatInvariant(scheduleTaskId, query)); + CallEndpoint("{0}/Execute/{1}{2}".FormatInvariant(_baseUrl, scheduleTaskId, query)); } private void Elapsed(object sender, System.Timers.ElapsedEventArgs e) diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs index 55ac7330ac..518e66169c 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs @@ -826,7 +826,7 @@ public ActionResult PreviewList(GridCommand command, int id, int totalRecords) } [HttpPost] - public ActionResult Execute(int id, string selectedIds, bool exportAll) + public ActionResult Execute(int id, string selectedIds) { if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageExports)) return AccessDeniedView(); @@ -835,10 +835,15 @@ public ActionResult Execute(int id, string selectedIds, bool exportAll) if (profile == null) return RedirectToAction("List"); - // TODO: - profile.CacheSelectedEntityIds(selectedIds); + Dictionary taskParams = null; - _taskScheduler.RunSingleTask(profile.SchedulingTaskId); + if (selectedIds.HasValue()) + { + taskParams = new Dictionary(); + taskParams.Add("SelectedIds", selectedIds); + } + + _taskScheduler.RunSingleTask(profile.SchedulingTaskId, taskParams); NotifyInfo(T("Admin.System.ScheduleTasks.RunNow.Progress")); diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Export/List.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Export/List.cshtml index 689da7f9a4..740e0447ce 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Export/List.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Export/List.cshtml @@ -18,7 +18,6 @@
-
@if(Model.Count > 0) diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Export/Preview.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Export/Preview.cshtml index b5e527976d..2bca030bc9 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Export/Preview.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Export/Preview.cshtml @@ -16,7 +16,6 @@
- @if (Model.LogFileExists) { @@ -42,8 +41,13 @@ e.preventDefault(); var form = $('#ProfileExportForm'), exportAll = $(this).attr('name') === 'ExportAll'; + + if (!exportAll && selectedIds.length === 0) { + EventBroker.publish("message", { title: '@T("Admin.Common.NoEntriesSelected")', type: 'warning' }); + return false; + } + form.find('[name=SelectedIds]').val(exportAll ? '' : selectedIds.join(',')); - form.find('[name=ExportAll]').val(exportAll.toString()); form.submit(); return false; }); From 48cc39feaea772e6a39f689540a4148af9f39389 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Thu, 12 Nov 2015 12:05:37 +0100 Subject: [PATCH 019/626] Further IDataExporter implementation --- .../DataExchange/IDataExporter.cs | 9 ++++- .../DataExchange/Internal/DataExportTask.cs | 7 +++- .../DataExchange/Internal/DataExporter.cs | 37 +++++++++---------- .../Internal/DataExporterContext.cs | 4 -- .../Controllers/ExportController.cs | 4 +- 5 files changed, 30 insertions(+), 31 deletions(-) diff --git a/src/Libraries/SmartStore.Services/DataExchange/IDataExporter.cs b/src/Libraries/SmartStore.Services/DataExchange/IDataExporter.cs index 843a15351e..b39c61fcf5 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/IDataExporter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/IDataExporter.cs @@ -1,7 +1,9 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Threading; using SmartStore.Core.Domain; +using SmartStore.Core.Domain.Catalog; using SmartStore.Core.Plugins; namespace SmartStore.Services.DataExchange @@ -13,7 +15,7 @@ public interface IDataExporter { DataExportResult Export(DataExportRequest request, CancellationToken cancellationToken); - IList Preview(DataExportRequest request); + IList Preview(DataExportRequest request, int pageIndex, int? totalRecords = null); int GetDataCount(DataExportRequest request); } @@ -35,6 +37,7 @@ public DataExportRequest(ExportProfile profile, Provider provid ProgressValueSetter = _voidProgressValueSetter; ProgressMessageSetter = _voidProgressMessageSetter; + EntitiesToExport = new List(); CustomData = new Dictionary(StringComparer.OrdinalIgnoreCase); } @@ -42,13 +45,15 @@ public DataExportRequest(ExportProfile profile, Provider provid public Provider Provider { get; private set; } - public IEnumerable EntitiesToExport { get; set; } + public IList EntitiesToExport { get; set; } public ProgressValueSetter ProgressValueSetter { get; set; } public ProgressMessageSetter ProgressMessageSetter { get; set; } public IDictionary CustomData { get; private set; } + public IQueryable ProductQuery { get; set; } + private static void SetProgress(int val, int max, string msg) { diff --git a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExportTask.cs b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExportTask.cs index ab5d8e40c5..54ed0768e6 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExportTask.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExportTask.cs @@ -1,4 +1,4 @@ -using System.Web; +using System.Linq; using SmartStore.Core.Localization; using SmartStore.Services.Tasks; @@ -47,7 +47,10 @@ public void Execute(TaskExecutionContext ctx) if (ctx.Parameters.ContainsKey("SelectedIds")) { - request.EntitiesToExport = ctx.Parameters["SelectedIds"].ToIntArray(); + request.EntitiesToExport = ctx.Parameters["SelectedIds"] + .SplitSafe(",") + .Select(x => x.ToInt()) + .ToList(); } // process! diff --git a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporter.cs b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporter.cs index cc263c1b5b..43cf433f7a 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporter.cs @@ -380,12 +380,12 @@ private IQueryable GetProductQuery(DataExporterContext ctx, int skip, i { IQueryable query = null; - if (ctx.QueryProducts == null) + if (ctx.Request.ProductQuery == null) { var searchContext = new ProductSearchContext { OrderBy = ProductSortingEnum.CreatedOn, - ProductIds = ctx.EntityIdsSelected, + ProductIds = ctx.Request.EntitiesToExport, StoreId = (ctx.Request.Profile.PerStore ? ctx.Store.Id : ctx.Filter.StoreId), VisibleIndividuallyOnly = true, PriceMin = ctx.Filter.PriceMinimum, @@ -421,7 +421,7 @@ private IQueryable GetProductQuery(DataExporterContext ctx, int skip, i } else { - query = ctx.QueryProducts; + query = ctx.Request.ProductQuery; } if (skip > 0) @@ -495,8 +495,8 @@ private IQueryable GetOrderQuery(DataExporterContext ctx, int skip, int t null, null); - if (ctx.EntityIdsSelected.Count > 0) - query = query.Where(x => ctx.EntityIdsSelected.Contains(x.Id)); + if (ctx.Request.EntitiesToExport.Count > 0) + query = query.Where(x => ctx.Request.EntitiesToExport.Contains(x.Id)); query = query.OrderByDescending(x => x.CreatedOnUtc); @@ -610,10 +610,8 @@ private IQueryable GetCustomerQuery(DataExporterContext ctx, int skip, .Expand(x => x.CustomerRoles) .Where(x => !x.Deleted); - if (ctx.EntityIdsSelected.Count > 0) - { - query = query.Where(x => ctx.EntityIdsSelected.Contains(x.Id)); - } + if (ctx.Request.EntitiesToExport.Count > 0) + query = query.Where(x => ctx.Request.EntitiesToExport.Contains(x.Id)); query = query.OrderByDescending(x => x.CreatedOnUtc); @@ -890,6 +888,11 @@ private void ExportCoreOuter(DataExporterContext ctx) throw new SmartException("Export aborted because the export provider is not valid"); } + foreach (var item in ctx.Request.CustomData) + { + ctx.ExecuteContext.CustomProperties.Add(item.Key, item.Value); + } + ctx.Log = logger; ctx.ExecuteContext.Log = logger; ctx.ProgressInfo = T("Admin.DataExchange.Export.ProgressInfo"); @@ -1025,13 +1028,15 @@ private void ExportCoreOuter(DataExporterContext ctx) ctx.DeliveryTimes.Clear(); ctx.CategoryPathes.Clear(); ctx.Categories.Clear(); - ctx.EntityIdsSelected.Clear(); ctx.ProductExportContext = null; ctx.OrderExportContext = null; ctx.ManufacturerExportContext = null; ctx.CategoryExportContext = null; ctx.CustomerExportContext = null; + ctx.Request.EntitiesToExport.Clear(); + ctx.Request.CustomData.Clear(); + ctx.ExecuteContext.CustomProperties.Clear(); ctx.ExecuteContext.Log = null; ctx.Log = null; @@ -1061,11 +1066,6 @@ public DataExportResult Export(DataExportRequest request, CancellationToken canc { var ctx = new DataExporterContext(request, cancellationToken); - if (request.EntitiesToExport != null) - { - ctx.EntityIdsSelected.AddRange(request.EntitiesToExport); - } - ExportCoreOuter(ctx); if (ctx.Result != null && ctx.Result.Succeeded && ctx.Result.Files.Count > 0) @@ -1089,7 +1089,7 @@ public DataExportResult Export(DataExportRequest request, CancellationToken canc else prefix = request.Provider.Value.EntityType.ToString(); - var selectedEntityCount = (request.EntitiesToExport == null ? 0 : request.EntitiesToExport.Count()); + var selectedEntityCount = (request.EntitiesToExport == null ? 0 : request.EntitiesToExport.Count); if (selectedEntityCount == 0) suffix = T("Common.All"); @@ -1102,11 +1102,8 @@ public DataExportResult Export(DataExportRequest request, CancellationToken canc return ctx.Result; } - public IList Preview(DataExportRequest request) + public IList Preview(DataExportRequest request, int pageIndex, int? totalRecords = null) { - var pageIndex = (request.CustomData.ContainsKey("PageIndex") ? (int)request.CustomData["PageIndex"] : 0); - var totalRecords = (request.CustomData.ContainsKey("TotalRecords") ? (int)request.CustomData["TotalRecords"] : 0); - var resultData = new List(); var cancellation = new CancellationTokenSource(TimeSpan.FromMinutes(5.0)); diff --git a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporterContext.cs b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporterContext.cs index b12b3a1bdb..23da17e069 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporterContext.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporterContext.cs @@ -1,6 +1,5 @@ using System.Collections.Generic; using System.IO; -using System.Linq; using System.Threading; using SmartStore.Core; using SmartStore.Core.Domain; @@ -37,7 +36,6 @@ public DataExporterContext( FolderContent = FileSystemHelper.TempDir(@"Profile\Export\{0}\Content".FormatInvariant(request.Profile.FolderName)); FolderRoot = System.IO.Directory.GetParent(FolderContent).FullName; - EntityIdsSelected = new List(); Categories = new Dictionary(); CategoryPathes = new Dictionary(); Countries = new Dictionary(); @@ -56,13 +54,11 @@ public DataExporterContext( ExecuteContext.Projection = XmlHelper.Deserialize(request.Profile.Projection); } - public List EntityIdsSelected { get; private set; } public List EntityIdsLoaded { get; set; } public int RecordCount { get; set; } public Dictionary RecordsPerStore { get; set; } public string ProgressInfo { get; set; } - public IQueryable QueryProducts { get; set; } public DataExportRequest Request { get; private set; } public CancellationToken CancellationToken { get; private set; } diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs index 518e66169c..354da99fe9 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs @@ -754,10 +754,8 @@ public ActionResult PreviewList(GridCommand command, int id, int totalRecords) var orderModel = new List(); var request = new DataExportRequest(profile, provider); - request.CustomData.Add("PageIndex", command.Page - 1); - request.CustomData.Add("TotalRecords", totalRecords); - var data = _dataExporter.Preview(request); + var data = _dataExporter.Preview(request, command.Page - 1, totalRecords); foreach (dynamic item in data) { From f685b80399f4584fccecd17c19af37756278ebe5 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Thu, 12 Nov 2015 17:16:49 +0100 Subject: [PATCH 020/626] Creating system export profiles --- .../Domain/DataExchange/ExportProfile.cs | 10 + .../Mapping/DataExchange/ExportProfileMap.cs | 1 + ...1511121139009_ExportFramework3.Designer.cs | 29 +++ .../201511121139009_ExportFramework3.cs | 193 ++++++++++++++++++ .../201511121139009_ExportFramework3.resx | 126 ++++++++++++ .../SmartStore.Data/SmartStore.Data.csproj | 7 + .../{Internal => }/DataExportTask.cs | 2 +- .../{Internal => }/DataExporter.cs | 3 +- .../{Internal => }/DynamicEntityHelper.cs | 3 +- .../DataExchange/ExportProfileService.cs | 8 +- .../Providers/CategoryXmlExportProvider.cs | 3 +- .../Providers/CustomerXlsxExportProvider.cs | 3 +- .../Providers/CustomerXmlExportProvider.cs | 3 +- .../ManufacturerXmlExportProvider.cs | 3 +- .../Providers/OrderXlsxExportProvider.cs | 3 +- .../Providers/OrderXmlExportProvider.cs | 3 +- .../Providers/ProductXlsxExportProvider.cs | 3 +- .../Providers/ProductXmlExportProvider.cs | 3 +- .../Providers/SubscriberCsvExportProvider.cs | 3 +- .../SmartStore.Services.csproj | 6 +- .../Localization/resources.en-us.xml | 2 +- .../Controllers/ExportController.cs | 2 + .../Models/DataExchange/ExportProfileModel.cs | 6 + .../Administration/Views/Export/Edit.cshtml | 25 ++- .../Administration/Views/Export/List.cshtml | 12 ++ 25 files changed, 432 insertions(+), 30 deletions(-) create mode 100644 src/Libraries/SmartStore.Data/Migrations/201511121139009_ExportFramework3.Designer.cs create mode 100644 src/Libraries/SmartStore.Data/Migrations/201511121139009_ExportFramework3.cs create mode 100644 src/Libraries/SmartStore.Data/Migrations/201511121139009_ExportFramework3.resx rename src/Libraries/SmartStore.Services/DataExchange/{Internal => }/DataExportTask.cs (96%) rename src/Libraries/SmartStore.Services/DataExchange/{Internal => }/DataExporter.cs (99%) rename src/Libraries/SmartStore.Services/DataExchange/{Internal => }/DynamicEntityHelper.cs (99%) diff --git a/src/Libraries/SmartStore.Core/Domain/DataExchange/ExportProfile.cs b/src/Libraries/SmartStore.Core/Domain/DataExchange/ExportProfile.cs index ea98e0838b..b49d8d76d1 100644 --- a/src/Libraries/SmartStore.Core/Domain/DataExchange/ExportProfile.cs +++ b/src/Libraries/SmartStore.Core/Domain/DataExchange/ExportProfile.cs @@ -32,11 +32,21 @@ public ExportProfile() ///
public string FileNamePattern { get; set; } + /// + /// The system name of the profile + /// + public string SystemName { get; set; } + /// /// The system name of the export provider /// public string ProviderSystemName { get; set; } + /// + /// Whether the profile is an unremovable system profile + /// + public bool IsSystemProfile { get; set; } + /// /// Whether the export profile is enabled /// diff --git a/src/Libraries/SmartStore.Data/Mapping/DataExchange/ExportProfileMap.cs b/src/Libraries/SmartStore.Data/Mapping/DataExchange/ExportProfileMap.cs index d54bf034e3..6e5e6758fe 100644 --- a/src/Libraries/SmartStore.Data/Mapping/DataExchange/ExportProfileMap.cs +++ b/src/Libraries/SmartStore.Data/Mapping/DataExchange/ExportProfileMap.cs @@ -12,6 +12,7 @@ public ExportProfileMap() this.Property(x => x.Name).IsRequired().HasMaxLength(100); this.Property(x => x.FolderName).IsRequired().HasMaxLength(100); + this.Property(x => x.SystemName).HasMaxLength(400); this.Property(x => x.ProviderSystemName).IsRequired().HasMaxLength(4000); this.Property(x => x.Filtering).IsMaxLength(); this.Property(x => x.Projection).IsMaxLength(); diff --git a/src/Libraries/SmartStore.Data/Migrations/201511121139009_ExportFramework3.Designer.cs b/src/Libraries/SmartStore.Data/Migrations/201511121139009_ExportFramework3.Designer.cs new file mode 100644 index 0000000000..634dd864d5 --- /dev/null +++ b/src/Libraries/SmartStore.Data/Migrations/201511121139009_ExportFramework3.Designer.cs @@ -0,0 +1,29 @@ +// +namespace SmartStore.Data.Migrations +{ + using System.CodeDom.Compiler; + using System.Data.Entity.Migrations; + using System.Data.Entity.Migrations.Infrastructure; + using System.Resources; + + [GeneratedCode("EntityFramework.Migrations", "6.1.3-40302")] + public sealed partial class ExportFramework3 : IMigrationMetadata + { + private readonly ResourceManager Resources = new ResourceManager(typeof(ExportFramework3)); + + string IMigrationMetadata.Id + { + get { return "201511121139009_ExportFramework3"; } + } + + string IMigrationMetadata.Source + { + get { return null; } + } + + string IMigrationMetadata.Target + { + get { return Resources.GetString("Target"); } + } + } +} diff --git a/src/Libraries/SmartStore.Data/Migrations/201511121139009_ExportFramework3.cs b/src/Libraries/SmartStore.Data/Migrations/201511121139009_ExportFramework3.cs new file mode 100644 index 0000000000..34a97d19bc --- /dev/null +++ b/src/Libraries/SmartStore.Data/Migrations/201511121139009_ExportFramework3.cs @@ -0,0 +1,193 @@ +namespace SmartStore.Data.Migrations +{ + using System.Data.Entity.Migrations; + using Setup; + using Core.Domain.Tasks; + using System.Collections.Generic; + using Core.Domain; + using System.Linq; + using Utilities; + + public partial class ExportFramework3 : DbMigration, ILocaleResourcesProvider, IDataSeeder + { + public override void Up() + { + AddColumn("dbo.ExportProfile", "SystemName", c => c.String(maxLength: 400)); + AddColumn("dbo.ExportProfile", "IsSystemProfile", c => c.Boolean(nullable: false)); + } + + public override void Down() + { + DropColumn("dbo.ExportProfile", "IsSystemProfile"); + DropColumn("dbo.ExportProfile", "SystemName"); + } + + public bool RollbackOnFailure + { + get { return false; } + } + + public void Seed(SmartObjectContext context) + { + context.MigrateLocaleResources(MigrateLocaleResources); + + var systemProfilesInfos = new List + { + new SystemProfileInfo { SystemName = "SmartStoreCategoryXml", ProviderSystemName = "Exports.SmartStoreCategoryXml", Name = "Category XML Export" }, + new SystemProfileInfo { SystemName = "SmartStoreCustomerXlsx", ProviderSystemName = "Exports.SmartStoreCustomerXlsx", Name = "Customer Excel Export" }, + new SystemProfileInfo { SystemName = "SmartStoreCustomerXml", ProviderSystemName = "Exports.SmartStoreCustomerXml", Name = "Customer XML Export" }, + new SystemProfileInfo { SystemName = "SmartStoreManufacturerXml", ProviderSystemName = "Exports.SmartStoreManufacturerXml", Name = "Manufacturer XML Export" }, + new SystemProfileInfo { SystemName = "SmartStoreOrderXlsx", ProviderSystemName = "Exports.SmartStoreOrderXlsx", Name = "Order Excel Export" }, + new SystemProfileInfo { SystemName = "SmartStoreOrderXml", ProviderSystemName = "Exports.SmartStoreOrderXml", Name = "Order XML Export" }, + new SystemProfileInfo { SystemName = "SmartStoreProductXlsx", ProviderSystemName = "Exports.SmartStoreProductXlsx", Name = "Product Excel Export" }, + new SystemProfileInfo { SystemName = "SmartStoreProductXml", ProviderSystemName = "Exports.SmartStoreProductXml", Name = "Product XML Export" }, + new SystemProfileInfo { SystemName = "SmartStoreNewsSubscriptionCsv", ProviderSystemName = "Exports.SmartStoreNewsSubscriptionCsv", Name = "Newsletter Subscribers CSV Export" } + }; + + var tasks = context.Set(); + var profiles = context.Set(); + + foreach (var profileInfo in systemProfilesInfos) + { + var profile = profiles.FirstOrDefault(x => x.IsSystemProfile && x.SystemName == profileInfo.SystemName && x.ProviderSystemName == profileInfo.ProviderSystemName); + + if (profile != null) + continue; + + var task = new ScheduleTask + { + CronExpression = "0 */6 * * *", // every six hours + Type = "SmartStore.Services.DataExchange.DataExportTask, SmartStore.Services", + Enabled = false, + StopOnError = false, + IsHidden = true + }; + + task.Name = string.Concat(profileInfo.Name, " task"); + + task = tasks.Add(task); + context.SaveChanges(); + + var seoName = SeoHelper.GetSeName(profileInfo.Name, true, false).Replace("/", "").Replace("-", ""); + + profile = new ExportProfile + { + IsSystemProfile = true, + Name = profileInfo.Name, + SystemName = profileInfo.SystemName, + ProviderSystemName = profileInfo.ProviderSystemName, + FolderName = string.Concat("sm-", seoName.Replace("export", "").ToValidPath().Truncate(50)), + FileNamePattern = "%Store.Id%-%Profile.Id%-%File.Index%-%Profile.SeoName%", + Enabled = true, + PerStore = false, + CreateZipArchive = false, + Cleanup = false, + SchedulingTaskId = task.Id + }; + + profile = profiles.Add(profile); + + task.Alias = profile.Id.ToString(); + + tasks.AddOrUpdate(task); + context.SaveChanges(); + } + } + + public void MigrateLocaleResources(LocaleResourcesBuilder builder) + { + builder.AddOrUpdate("Enums.SmartStore.Core.Domain.DataExchange.ExportEntityType.NewsLetterSubscription", + "Newsletter Subscribers", + "Newsletter Abonnenten"); + + + builder.AddOrUpdate("Providers.FriendlyName.Exports.SmartStoreCategoryXml", + "Category XML Export", + "Warengruppen XML Export"); + builder.AddOrUpdate("Providers.Description.Exports.SmartStoreCategoryXml", + "Allows to export category data in XML format.", + "Ermglicht den Export von Warengruppendaten im XML Format."); + + builder.AddOrUpdate("Providers.FriendlyName.Exports.SmartStoreCustomerXlsx", + "Customer Excel Export", + "Kunden Excel Export"); + builder.AddOrUpdate("Providers.Description.Exports.SmartStoreCustomerXlsx", + "Allows to export customer data in Excel format.", + "Ermglicht den Export von Kundendaten im Excel Format."); + + builder.AddOrUpdate("Providers.FriendlyName.Exports.SmartStoreCustomerXml", + "Customer XML Export", + "Kunden XML Export"); + builder.AddOrUpdate("Providers.Description.Exports.SmartStoreCustomerXml", + "Allows to export customer data in XML format.", + "Ermglicht den Export von Kundendaten im XML Format."); + + builder.AddOrUpdate("Providers.FriendlyName.Exports.SmartStoreManufacturerXml", + "Manufacturer XML Export", + "Hersteller XML Export"); + builder.AddOrUpdate("Providers.Description.Exports.SmartStoreManufacturerXml", + "Allows to export manufacturer data in XML format.", + "Ermglicht den Export von Herstellerdaten im XML Format."); + + builder.AddOrUpdate("Providers.FriendlyName.Exports.SmartStoreOrderXlsx", + "Order Excel Export", + "Auftrags Excel Export"); + builder.AddOrUpdate("Providers.Description.Exports.SmartStoreOrderXlsx", + "Allows to export order data in Excel format.", + "Ermglicht den Export von Auftragsdaten im Excel Format."); + + builder.AddOrUpdate("Providers.FriendlyName.Exports.SmartStoreOrderXml", + "Order XML Export", + "Auftrags XML Export"); + builder.AddOrUpdate("Providers.Description.Exports.SmartStoreOrderXml", + "Allows to export order data in XML format.", + "Ermglicht den Export von Auftragsdaten im XML Format."); + + builder.AddOrUpdate("Providers.FriendlyName.Exports.SmartStoreProductXlsx", + "Product Excel Export", + "Produkt Excel Export"); + builder.AddOrUpdate("Providers.Description.Exports.SmartStoreProductXlsx", + "Allows to export product data in Excel format.", + "Ermglicht den Export von Produktdaten im Excel Format."); + + builder.AddOrUpdate("Providers.FriendlyName.Exports.SmartStoreProductXml", + "Product XML Export", + "Produkt XML Export"); + builder.AddOrUpdate("Providers.Description.Exports.SmartStoreProductXml", + "Allows to export product data in XML format.", + "Ermglicht den Export von Produktdaten im XML Format."); + + builder.AddOrUpdate("Providers.FriendlyName.Exports.SmartStoreNewsSubscriptionCsv", + "Newsletter Subscribers CSV Export", + "Newsletter Abonnenten CSV Export"); + builder.AddOrUpdate("Providers.Description.Exports.SmartStoreNewsSubscriptionCsv", + "Allows to export newsletter subscriber data in CSV format.", + "Ermglicht den Export von Newsletter Abonnentendaten im CSV Format."); + + + builder.AddOrUpdate("Admin.DataExchange.Export.SystemName", + "System name of profile", + "Systemname des Profils", + "The system name of the export profile.", + "Der Systemname des Exportprofils."); + + builder.AddOrUpdate("Admin.DataExchange.Export.IsSystemProfile", + "System profile", + "Systemprofil", + "Indicates whether the export profile is a system profile. System profiles cannot be removed.", + "Gibt an, ob es sich bei dem Exportprofil um eine Systemprofil handelt. Systemprofile knnen nicht entfernt werden."); + + builder.AddOrUpdate("Admin.DataExchange.Export.CannotDeleteSystemProfile", + "Cannot delete a system export profile.", + "Ein System-Exportprofil kann nicht gelscht werden."); + } + } + + + internal class SystemProfileInfo + { + public string SystemName { get; set; } + public string ProviderSystemName { get; set; } + public string Name { get; set; } + } +} \ No newline at end of file diff --git a/src/Libraries/SmartStore.Data/Migrations/201511121139009_ExportFramework3.resx b/src/Libraries/SmartStore.Data/Migrations/201511121139009_ExportFramework3.resx new file mode 100644 index 0000000000..1ed5a1d758 --- /dev/null +++ b/src/Libraries/SmartStore.Data/Migrations/201511121139009_ExportFramework3.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 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 + + + dbo + + \ No newline at end of file diff --git a/src/Libraries/SmartStore.Data/SmartStore.Data.csproj b/src/Libraries/SmartStore.Data/SmartStore.Data.csproj index 8764a6a9ed..b328653e66 100644 --- a/src/Libraries/SmartStore.Data/SmartStore.Data.csproj +++ b/src/Libraries/SmartStore.Data/SmartStore.Data.csproj @@ -366,6 +366,10 @@ 201509150931528_ExportFramework2.cs + + + 201511121139009_ExportFramework3.cs + @@ -687,6 +691,9 @@ 201509150931528_ExportFramework2.cs + + 201511121139009_ExportFramework3.cs + diff --git a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExportTask.cs b/src/Libraries/SmartStore.Services/DataExchange/DataExportTask.cs similarity index 96% rename from src/Libraries/SmartStore.Services/DataExchange/Internal/DataExportTask.cs rename to src/Libraries/SmartStore.Services/DataExchange/DataExportTask.cs index 54ed0768e6..0622be6566 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExportTask.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/DataExportTask.cs @@ -2,7 +2,7 @@ using SmartStore.Core.Localization; using SmartStore.Services.Tasks; -namespace SmartStore.Services.DataExchange.Internal +namespace SmartStore.Services.DataExchange { // note: namespace persisted in ScheduleTask.Type public partial class DataExportTask : ITask diff --git a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporter.cs b/src/Libraries/SmartStore.Services/DataExchange/DataExporter.cs similarity index 99% rename from src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporter.cs rename to src/Libraries/SmartStore.Services/DataExchange/DataExporter.cs index 43cf433f7a..b409401da6 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/DataExporter.cs @@ -21,6 +21,7 @@ using SmartStore.Services.Catalog; using SmartStore.Services.Common; using SmartStore.Services.Customers; +using SmartStore.Services.DataExchange.Internal; using SmartStore.Services.Directory; using SmartStore.Services.Helpers; using SmartStore.Services.Localization; @@ -33,7 +34,7 @@ using SmartStore.Utilities; using SmartStore.Utilities.Threading; -namespace SmartStore.Services.DataExchange.Internal +namespace SmartStore.Services.DataExchange { public partial class DataExporter : IDataExporter { diff --git a/src/Libraries/SmartStore.Services/DataExchange/Internal/DynamicEntityHelper.cs b/src/Libraries/SmartStore.Services/DataExchange/DynamicEntityHelper.cs similarity index 99% rename from src/Libraries/SmartStore.Services/DataExchange/Internal/DynamicEntityHelper.cs rename to src/Libraries/SmartStore.Services/DataExchange/DynamicEntityHelper.cs index e3de6b5e56..73cb0ae431 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Internal/DynamicEntityHelper.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/DynamicEntityHelper.cs @@ -21,10 +21,11 @@ using SmartStore.Core.Domain.Stores; using SmartStore.Core.Html; using SmartStore.Services.Catalog; +using SmartStore.Services.DataExchange.Internal; using SmartStore.Services.Localization; using SmartStore.Services.Seo; -namespace SmartStore.Services.DataExchange.Internal +namespace SmartStore.Services.DataExchange { public partial class DataExporter { diff --git a/src/Libraries/SmartStore.Services/DataExchange/ExportProfileService.cs b/src/Libraries/SmartStore.Services/DataExchange/ExportProfileService.cs index 414e5c073a..f2860ed481 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/ExportProfileService.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/ExportProfileService.cs @@ -104,7 +104,7 @@ public virtual ExportProfile InsertExportProfile(Provider provi task.LastEndUtc = task.LastStartUtc = task.LastSuccessUtc = null; } - task.Name = string.Concat(name, " export task"); + task.Name = string.Concat(name, " task"); _scheduleTaskService.InsertTask(task); @@ -196,6 +196,9 @@ public virtual void DeleteExportProfile(ExportProfile profile) if (profile == null) throw new ArgumentNullException("profile"); + if (profile.IsSystemProfile) + throw new SmartException(_localizationService.GetResource("Admin.DataExchange.Export.CannotDeleteSystemProfile")); + int scheduleTaskId = profile.SchedulingTaskId; var folder = profile.GetExportFolder(); @@ -224,7 +227,8 @@ from x in _exportProfileRepository.Table.Expand(x => x.ScheduleTask) } query = query - .OrderBy(x => x.ProviderSystemName) + .OrderBy(x => x.IsSystemProfile) + .ThenBy(x => x.ProviderSystemName) .ThenBy(x => x.Name); return query; diff --git a/src/Libraries/SmartStore.Services/DataExchange/Providers/CategoryXmlExportProvider.cs b/src/Libraries/SmartStore.Services/DataExchange/Providers/CategoryXmlExportProvider.cs index 401b9a165c..8733ac6a1e 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Providers/CategoryXmlExportProvider.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Providers/CategoryXmlExportProvider.cs @@ -10,8 +10,7 @@ namespace SmartStore.Services.DataExchange.Providers /// Exports XML formatted category data to a file ///
[SystemName("Exports.SmartStoreCategoryXml")] - [FriendlyName("SmartStore XML category export")] - [IsHidden(true)] + [FriendlyName("Category XML Export")] public class CategoryXmlExportProvider : ExportProviderBase { public static string SystemName diff --git a/src/Libraries/SmartStore.Services/DataExchange/Providers/CustomerXlsxExportProvider.cs b/src/Libraries/SmartStore.Services/DataExchange/Providers/CustomerXlsxExportProvider.cs index 133ea6e3a7..75437762ee 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Providers/CustomerXlsxExportProvider.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Providers/CustomerXlsxExportProvider.cs @@ -14,8 +14,7 @@ namespace SmartStore.Services.DataExchange.Providers /// Exports Excel formatted customer data to a file ///
[SystemName("Exports.SmartStoreCustomerXlsx")] - [FriendlyName("SmartStore Excel customer export")] - [IsHidden(true)] + [FriendlyName("Customer Excel Export")] public class CustomerXlsxExportProvider : ExportProviderBase { private string[] Properties diff --git a/src/Libraries/SmartStore.Services/DataExchange/Providers/CustomerXmlExportProvider.cs b/src/Libraries/SmartStore.Services/DataExchange/Providers/CustomerXmlExportProvider.cs index 7b7611fb2a..a5f7a56048 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Providers/CustomerXmlExportProvider.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Providers/CustomerXmlExportProvider.cs @@ -9,8 +9,7 @@ namespace SmartStore.Services.DataExchange.Providers /// Exports XML formatted customer data to a file ///
[SystemName("Exports.SmartStoreCustomerXml")] - [FriendlyName("SmartStore XML customer export")] - [IsHidden(true)] + [FriendlyName("Customer XML Export")] public class CustomerXmlExportProvider : ExportProviderBase { public static string SystemName diff --git a/src/Libraries/SmartStore.Services/DataExchange/Providers/ManufacturerXmlExportProvider.cs b/src/Libraries/SmartStore.Services/DataExchange/Providers/ManufacturerXmlExportProvider.cs index 74eb5551a7..e4bb40c427 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Providers/ManufacturerXmlExportProvider.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Providers/ManufacturerXmlExportProvider.cs @@ -10,8 +10,7 @@ namespace SmartStore.Services.DataExchange.Providers /// Exports XML formatted manufacturer data to a file /// [SystemName("Exports.SmartStoreManufacturerXml")] - [FriendlyName("SmartStore XML manufacturer export")] - [IsHidden(true)] + [FriendlyName("Manufacturer XML Export")] public class ManufacturerXmlExportProvider : ExportProviderBase { public static string SystemName diff --git a/src/Libraries/SmartStore.Services/DataExchange/Providers/OrderXlsxExportProvider.cs b/src/Libraries/SmartStore.Services/DataExchange/Providers/OrderXlsxExportProvider.cs index b36b4286d9..f6b34744d0 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Providers/OrderXlsxExportProvider.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Providers/OrderXlsxExportProvider.cs @@ -12,8 +12,7 @@ namespace SmartStore.Services.DataExchange.Providers /// Exports Excel formatted order data to a file /// [SystemName("Exports.SmartStoreOrderXlsx")] - [FriendlyName("SmartStore Excel order export")] - [IsHidden(true)] + [FriendlyName("Order Excel Export")] public class OrderXlsxExportProvider : ExportProviderBase { private string[] Properties diff --git a/src/Libraries/SmartStore.Services/DataExchange/Providers/OrderXmlExportProvider.cs b/src/Libraries/SmartStore.Services/DataExchange/Providers/OrderXmlExportProvider.cs index 6a878ddb84..85069df675 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Providers/OrderXmlExportProvider.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Providers/OrderXmlExportProvider.cs @@ -13,8 +13,7 @@ namespace SmartStore.Services.DataExchange.Providers /// Exports XML formatted order data to a file /// [SystemName("Exports.SmartStoreOrderXml")] - [FriendlyName("SmartStore XML order export")] - [IsHidden(true)] + [FriendlyName("Order XML Export")] public class OrderXmlExportProvider : ExportProviderBase { public static string SystemName diff --git a/src/Libraries/SmartStore.Services/DataExchange/Providers/ProductXlsxExportProvider.cs b/src/Libraries/SmartStore.Services/DataExchange/Providers/ProductXlsxExportProvider.cs index e908fa8001..284388bbb0 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Providers/ProductXlsxExportProvider.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Providers/ProductXlsxExportProvider.cs @@ -18,8 +18,7 @@ namespace SmartStore.Services.DataExchange.Providers /// Exports Excel formatted product data to a file /// [SystemName("Exports.SmartStoreProductXlsx")] - [FriendlyName("SmartStore Excel product export")] - [IsHidden(true)] + [FriendlyName("Product Excel Export")] public class ProductXlsxExportProvider : ExportProviderBase { private readonly ILanguageService _languageService; diff --git a/src/Libraries/SmartStore.Services/DataExchange/Providers/ProductXmlExportProvider.cs b/src/Libraries/SmartStore.Services/DataExchange/Providers/ProductXmlExportProvider.cs index 4c2f86ccfd..a5f88db4b4 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Providers/ProductXmlExportProvider.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Providers/ProductXmlExportProvider.cs @@ -9,8 +9,7 @@ namespace SmartStore.Services.DataExchange.Providers /// Exports XML formatted product data to a file /// [SystemName("Exports.SmartStoreProductXml")] - [FriendlyName("SmartStore XML product export")] - [IsHidden(true)] + [FriendlyName("Product XML Export")] public class ProductXmlExportProvider : ExportProviderBase { public static string SystemName diff --git a/src/Libraries/SmartStore.Services/DataExchange/Providers/SubscriberCsvExportProvider.cs b/src/Libraries/SmartStore.Services/DataExchange/Providers/SubscriberCsvExportProvider.cs index bf8b192421..ff2873ee92 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Providers/SubscriberCsvExportProvider.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Providers/SubscriberCsvExportProvider.cs @@ -11,8 +11,7 @@ namespace SmartStore.Services.DataExchange.Providers /// Exports CSV formatted newsletter subscription data to a file /// [SystemName("Exports.SmartStoreNewsSubscriptionCsv")] - [FriendlyName("SmartStore CSV newsletter subscription export")] - [IsHidden(true)] + [FriendlyName("Newsletter Subscribers CSV Export")] public class SubscriberCsvExportProvider : ExportProviderBase { public static string SystemName diff --git a/src/Libraries/SmartStore.Services/SmartStore.Services.csproj b/src/Libraries/SmartStore.Services/SmartStore.Services.csproj index 83fe5c10e4..ec4af99cbd 100644 --- a/src/Libraries/SmartStore.Services/SmartStore.Services.csproj +++ b/src/Libraries/SmartStore.Services/SmartStore.Services.csproj @@ -168,9 +168,9 @@ - + - + @@ -198,7 +198,7 @@ - + diff --git a/src/Plugins/SmartStore.GoogleMerchantCenter/Localization/resources.en-us.xml b/src/Plugins/SmartStore.GoogleMerchantCenter/Localization/resources.en-us.xml index 8e7528f68e..a80721be22 100644 --- a/src/Plugins/SmartStore.GoogleMerchantCenter/Localization/resources.en-us.xml +++ b/src/Plugins/SmartStore.GoogleMerchantCenter/Localization/resources.en-us.xml @@ -9,7 +9,7 @@ Google Merchant Center XML feed - Allows you to export product data in the XML feed format of Google Merchant Center (GMC). + Allows to export product data in XML feed format of Google Merchant Center (GMC). diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs index 354da99fe9..f15c4fe3a0 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs @@ -104,6 +104,8 @@ private void PrepareProfileModel(ExportProfileModel model, ExportProfile profile { model.Id = profile.Id; model.Name = profile.Name; + model.SystemName = profile.SystemName; + model.IsSystemProfile = profile.IsSystemProfile; model.ProviderSystemName = profile.ProviderSystemName; model.FolderName = profile.FolderName; model.FileNamePattern = profile.FileNamePattern; diff --git a/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ExportProfileModel.cs b/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ExportProfileModel.cs index 493636f238..7ea59f0921 100644 --- a/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ExportProfileModel.cs +++ b/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ExportProfileModel.cs @@ -24,6 +24,12 @@ public partial class ExportProfileModel : EntityModelBase [SmartResourceDisplayName("Admin.DataExchange.Export.Name")] public string Name { get; set; } + [SmartResourceDisplayName("Admin.DataExchange.Export.SystemName")] + public string SystemName { get; set; } + + [SmartResourceDisplayName("Admin.DataExchange.Export.IsSystemProfile")] + public bool IsSystemProfile { get; set; } + [SmartResourceDisplayName("Admin.DataExchange.Export.ProviderSystemName")] public string ProviderSystemName { get; set; } public List AvailableProviders { get; set; } diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Export/Edit.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Export/Edit.cshtml index 55bac26fec..ecf22fd744 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Export/Edit.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Export/Edit.cshtml @@ -35,9 +35,12 @@ - + @if (!Model.IsSystemProfile) + { + + } @@ -73,6 +76,22 @@ @Html.ValidationMessageFor(x => x.Name) + + + @Html.SmartLabelFor(x => x.SystemName) + + +
@(Model.SystemName.NaIfEmpty())
+ + + + + @Html.SmartLabelFor(x => x.IsSystemProfile) + + + @T(Model.IsSystemProfile ? "Admin.Common.Yes" : "Admin.Common.No") + + @Html.SmartLabelFor(x => x.Enabled) diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Export/List.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Export/List.cshtml index 740e0447ce..6448df05a3 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Export/List.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Export/List.cshtml @@ -31,6 +31,7 @@ @T("Common.Enabled") @T("Admin.DataExchange.Export.EntityType") @T("Admin.DataExchange.Export.FileExtension") + @T("Admin.DataExchange.Export.IsSystemProfile") @T("Admin.System.ScheduleTasks.LastStart") @T("Admin.System.ScheduleTasks.NextRun") @T("Admin.Common.Actions") @@ -45,12 +46,20 @@ @profile.Name + @if (profile.SystemName.HasValue()) + { +
@profile.SystemName
+ } @if (profile.Provider.ConfigurationUrl.HasValue()) { @profile.Provider.FriendlyName.NaIfEmpty() } + else + { + @profile.Provider.FriendlyName.NaIfEmpty() + }
@profile.ProviderSystemName
@@ -62,6 +71,9 @@ @Html.IconForFileExtension(profile.Provider.FileExtension, true) + + @Html.SymbolForBool(profile.IsSystemProfile) +
@Html.Partial("~/Administration/Views/ScheduleTask/_LastRun.cshtml", profile.TaskModel) From ef722954594c39f1f9aa7c99ea8515ca7607ee4c Mon Sep 17 00:00:00 2001 From: Murat Cakir Date: Thu, 12 Nov 2015 20:52:29 +0100 Subject: [PATCH 021/626] Export: Added RowExportingEvent --- .../DataExchange/DataExporter.cs | 15 +++--- .../DataExchange/DynamicEntityHelper.cs | 54 +++++++++++++++++-- .../DataExchange/Events/RowExportingEvent.cs | 17 ++++++ .../SmartStore.Services.csproj | 1 + 4 files changed, 77 insertions(+), 10 deletions(-) create mode 100644 src/Libraries/SmartStore.Services/DataExchange/Events/RowExportingEvent.cs diff --git a/src/Libraries/SmartStore.Services/DataExchange/DataExporter.cs b/src/Libraries/SmartStore.Services/DataExchange/DataExporter.cs index b409401da6..b09801ff15 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/DataExporter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/DataExporter.cs @@ -1074,21 +1074,22 @@ public DataExportResult Export(DataExportRequest request, CancellationToken canc string prefix = null; string suffix = null; var extension = Path.GetExtension(ctx.Result.Files.First().FileName); + var provider = request.Provider.Value; - if (request.Provider.Value.EntityType == ExportEntityType.Product) + if (provider.EntityType == ExportEntityType.Product) prefix = T("Admin.Catalog.Products"); - else if (request.Provider.Value.EntityType == ExportEntityType.Order) + else if (provider.EntityType == ExportEntityType.Order) prefix = T("Admin.Orders"); - else if (request.Provider.Value.EntityType == ExportEntityType.Category) + else if (provider.EntityType == ExportEntityType.Category) prefix = T("Admin.Catalog.Categories"); - else if (request.Provider.Value.EntityType == ExportEntityType.Manufacturer) + else if (provider.EntityType == ExportEntityType.Manufacturer) prefix = T("Admin.Catalog.Manufacturers"); - else if (request.Provider.Value.EntityType == ExportEntityType.Customer) + else if (provider.EntityType == ExportEntityType.Customer) prefix = T("Admin.Customers"); - else if (request.Provider.Value.EntityType == ExportEntityType.NewsLetterSubscription) + else if (provider.EntityType == ExportEntityType.NewsLetterSubscription) prefix = T("Admin.Promotions.NewsLetterSubscriptions"); else - prefix = request.Provider.Value.EntityType.ToString(); + prefix = provider.EntityType.ToString(); var selectedEntityCount = (request.EntitiesToExport == null ? 0 : request.EntitiesToExport.Count); diff --git a/src/Libraries/SmartStore.Services/DataExchange/DynamicEntityHelper.cs b/src/Libraries/SmartStore.Services/DataExchange/DynamicEntityHelper.cs index 73cb0ae431..7faca463f9 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/DynamicEntityHelper.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/DynamicEntityHelper.cs @@ -21,6 +21,7 @@ using SmartStore.Core.Domain.Stores; using SmartStore.Core.Html; using SmartStore.Services.Catalog; +using SmartStore.Services.DataExchange.Events; using SmartStore.Services.DataExchange.Internal; using SmartStore.Services.Localization; using SmartStore.Services.Seo; @@ -973,6 +974,14 @@ private List Convert(DataExporterContext ctx, Product product) result.Add(dynObject); } + _services.EventPublisher.Publish(new RowExportingEvent + { + Row = dynObject, + EntityType = ExportEntityType.Product, + ExportRequest = ctx.Request, + ExecuteContext = ctx.ExecuteContext + }); + return result; } @@ -1042,6 +1051,14 @@ private List Convert(DataExporterContext ctx, Order order) result.Add(dynObject); + _services.EventPublisher.Publish(new RowExportingEvent + { + Row = dynObject, + EntityType = ExportEntityType.Order, + ExportRequest = ctx.Request, + ExecuteContext = ctx.ExecuteContext + }); + return result; } @@ -1073,13 +1090,21 @@ private List Convert(DataExporterContext ctx, Manufacturer manufacturer result.Add(dynObject); + _services.EventPublisher.Publish(new RowExportingEvent + { + Row = dynObject, + EntityType = ExportEntityType.Manufacturer, + ExportRequest = ctx.Request, + ExecuteContext = ctx.ExecuteContext + }); + return result; } private List Convert(DataExporterContext ctx, Category category) { var result = new List(); - + var productCategories = ctx.CategoryExportContext.ProductCategories.Load(category.Id); dynamic dynObject = ToDynamic(ctx, category); @@ -1104,6 +1129,14 @@ private List Convert(DataExporterContext ctx, Category category) result.Add(dynObject); + _services.EventPublisher.Publish(new RowExportingEvent + { + Row = dynObject, + EntityType = ExportEntityType.Category, + ExportRequest = ctx.Request, + ExecuteContext = ctx.ExecuteContext + }); + return result; } @@ -1140,16 +1173,31 @@ private List Convert(DataExporterContext ctx, Customer customer) result.Add(dynObject); + _services.EventPublisher.Publish(new RowExportingEvent + { + Row = dynObject, + EntityType = ExportEntityType.Customer, + ExportRequest = ctx.Request, + ExecuteContext = ctx.ExecuteContext + }); + return result; } private List Convert(DataExporterContext ctx, NewsLetterSubscription subscription) { var result = new List(); - dynamic dynObject = ToDynamic(ctx, subscription); - result.Add(dynObject); + + _services.EventPublisher.Publish(new RowExportingEvent + { + Row = dynObject, + EntityType = ExportEntityType.NewsLetterSubscription, + ExportRequest = ctx.Request, + ExecuteContext = ctx.ExecuteContext + }); + return result; } } diff --git a/src/Libraries/SmartStore.Services/DataExchange/Events/RowExportingEvent.cs b/src/Libraries/SmartStore.Services/DataExchange/Events/RowExportingEvent.cs new file mode 100644 index 0000000000..31922ae3b9 --- /dev/null +++ b/src/Libraries/SmartStore.Services/DataExchange/Events/RowExportingEvent.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using SmartStore.Core.Domain.DataExchange; + +namespace SmartStore.Services.DataExchange.Events +{ + public class RowExportingEvent + { + public dynamic Row { get; internal set; } + public ExportEntityType EntityType { get; internal set; } + public DataExportRequest ExportRequest { get; internal set; } + public IExportExecuteContext ExecuteContext { get; internal set; } + } +} diff --git a/src/Libraries/SmartStore.Services/SmartStore.Services.csproj b/src/Libraries/SmartStore.Services/SmartStore.Services.csproj index ec4af99cbd..0c121d3896 100644 --- a/src/Libraries/SmartStore.Services/SmartStore.Services.csproj +++ b/src/Libraries/SmartStore.Services/SmartStore.Services.csproj @@ -166,6 +166,7 @@ + From c468baf706b86c3965f424f16c140f3b97ddb438 Mon Sep 17 00:00:00 2001 From: Murat Cakir Date: Thu, 12 Nov 2015 21:06:22 +0100 Subject: [PATCH 022/626] Export: some experimenting with RowExportingEvent --- .../DataExchange/Events/RowExportingEvent.cs | 4 +++ .../SmartStore.GoogleMerchantCenter/Events.cs | 32 +++++++++++++++++-- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/Libraries/SmartStore.Services/DataExchange/Events/RowExportingEvent.cs b/src/Libraries/SmartStore.Services/DataExchange/Events/RowExportingEvent.cs index 31922ae3b9..0b1dbcc017 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Events/RowExportingEvent.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Events/RowExportingEvent.cs @@ -7,6 +7,10 @@ namespace SmartStore.Services.DataExchange.Events { + // TODO: Another event message must be implemented, say 'ColumnsBuildingEvent' + // The consumer of this event (most likely a plugin) could push a list of specific column headers + // into global the export definition. + public class RowExportingEvent { public dynamic Row { get; internal set; } diff --git a/src/Plugins/SmartStore.GoogleMerchantCenter/Events.cs b/src/Plugins/SmartStore.GoogleMerchantCenter/Events.cs index 5ca8aeb5dc..4d0019134f 100644 --- a/src/Plugins/SmartStore.GoogleMerchantCenter/Events.cs +++ b/src/Plugins/SmartStore.GoogleMerchantCenter/Events.cs @@ -5,12 +5,16 @@ using SmartStore.GoogleMerchantCenter.Services; using SmartStore.Web.Framework.Events; using SmartStore.Web.Framework.Mvc; +using SmartStore.Services.DataExchange.Events; +using SmartStore.Core.Domain.DataExchange; +using SmartStore.Core.Domain.Catalog; namespace SmartStore.GoogleMerchantCenter { public class Events : IConsumer, - IConsumer + IConsumer/*, + IConsumer*/ { private readonly IGoogleFeedService _googleService; @@ -18,7 +22,7 @@ public Events(IGoogleFeedService googleService) { this._googleService = googleService; } - + public void HandleEvent(TabStripCreated eventMessage) { if (eventMessage.TabStripName == "product-edit") @@ -33,6 +37,30 @@ public void HandleEvent(TabStripCreated eventMessage) } } + //public void HandleEvent(RowExportingEvent eventMessage) + //{ + // if (eventMessage.EntityType != ExportEntityType.Product) + // return; + + // var row = eventMessage.Row; + // var product = eventMessage.Row.Entity as Product; + + // if (product == null) + // return; + + // var gmc = _googleService.GetGoogleProductRecord(product.Id); + // if (gmc == null) + // return; + + // row["_GMC_AgeGroup"] = gmc.AgeGroup; + // row["_GMC_Color"] = gmc.Color; + // row["_GMC_Gender"] = gmc.Gender; + // row["_GMC_Size"] = gmc.Size; + // row["_GMC_Taxonomy"] = gmc.Taxonomy; + // row["_GMC_Material"] = gmc.Material; + // row["_GMC_Pattern"] = gmc.Pattern; + //} + public void HandleEvent(ModelBoundEvent eventMessage) { if (!eventMessage.BoundModel.CustomProperties.ContainsKey("GMC")) From 5f74aecb89db44a7eee2d3884b1838d35d691c2c Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Fri, 13 Nov 2015 12:46:05 +0100 Subject: [PATCH 023/626] Export preview for all supported entity types --- .../201511121139009_ExportFramework3.cs | 1 + .../DataExchange/DataExporter.cs | 11 +- .../DataExchange/DynamicEntityHelper.cs | 21 ++ .../Controllers/ExportController.cs | 138 +++++++-- .../Models/DataExchange/ExportPreviewModel.cs | 78 +++++ .../Administration/Views/Category/List.cshtml | 9 +- .../Views/Export/Preview.cshtml | 286 +++++++++++++----- .../Views/Manufacturer/List.cshtml | 58 ++-- 8 files changed, 468 insertions(+), 134 deletions(-) diff --git a/src/Libraries/SmartStore.Data/Migrations/201511121139009_ExportFramework3.cs b/src/Libraries/SmartStore.Data/Migrations/201511121139009_ExportFramework3.cs index 34a97d19bc..132d36fee6 100644 --- a/src/Libraries/SmartStore.Data/Migrations/201511121139009_ExportFramework3.cs +++ b/src/Libraries/SmartStore.Data/Migrations/201511121139009_ExportFramework3.cs @@ -86,6 +86,7 @@ public void Seed(SmartObjectContext context) }; profile = profiles.Add(profile); + context.SaveChanges(); task.Alias = profile.Id.ToString(); diff --git a/src/Libraries/SmartStore.Services/DataExchange/DataExporter.cs b/src/Libraries/SmartStore.Services/DataExchange/DataExporter.cs index b09801ff15..d839d3d839 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/DataExporter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/DataExporter.cs @@ -540,6 +540,9 @@ private IQueryable GetManufacturerQuery(DataExporterContext ctx, i var query = _manufacturerService.Value.GetManufacturers(showHidden, storeId); + if (ctx.Request.EntitiesToExport.Count > 0) + query = query.Where(x => ctx.Request.EntitiesToExport.Contains(x.Id)); + query = query.OrderBy(x => x.DisplayOrder); if (skip > 0) @@ -573,6 +576,9 @@ private IQueryable GetCategoryQuery(DataExporterContext ctx, int skip, var query = _categoryService.Value.GetCategories(null, showHidden, null, true, storeId); + if (ctx.Request.EntitiesToExport.Count > 0) + query = query.Where(x => ctx.Request.EntitiesToExport.Contains(x.Id)); + query = query .OrderBy(x => x.ParentCategoryId) .ThenBy(x => x.DisplayOrder); @@ -647,9 +653,10 @@ private IQueryable GetNewsLetterSubscriptionQuery(DataEx var query = _subscriptionRepository.Value.TableUntracked; if (storeId > 0) - { query = query.Where(x => x.StoreId == storeId); - } + + if (ctx.Request.EntitiesToExport.Count > 0) + query = query.Where(x => ctx.Request.EntitiesToExport.Contains(x.Id)); query = query .OrderBy(x => x.StoreId) diff --git a/src/Libraries/SmartStore.Services/DataExchange/DynamicEntityHelper.cs b/src/Libraries/SmartStore.Services/DataExchange/DynamicEntityHelper.cs index 7faca463f9..cb964a59f8 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/DynamicEntityHelper.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/DynamicEntityHelper.cs @@ -392,6 +392,8 @@ private dynamic ToDynamic(DataExporterContext ctx, Customer customer) result._GenericAttributes = null; result._HasNewsletterSubscription = false; + result._FullName = null; + return result; } @@ -1171,6 +1173,24 @@ private List Convert(DataExporterContext ctx, Customer customer) dynObject._HasNewsletterSubscription = ctx.NewsletterSubscriptions.Contains(customer.Email, StringComparer.CurrentCultureIgnoreCase); + var attrFirstName = genericAttributes.FirstOrDefault(x => x.Key == SystemCustomerAttributeNames.FirstName); + var attrLastName = genericAttributes.FirstOrDefault(x => x.Key == SystemCustomerAttributeNames.LastName); + + string firstName = (attrFirstName == null ? "" : attrFirstName.Value); + string lastName = (attrLastName == null ? "" : attrLastName.Value); + + if (firstName.IsEmpty() && lastName.IsEmpty()) + { + var address = customer.Addresses.FirstOrDefault(); + if (address != null) + { + firstName = address.FirstName; + lastName = address.LastName; + } + } + + dynObject._FullName = firstName.Grow(lastName, " "); + result.Add(dynObject); _services.EventPublisher.Publish(new RowExportingEvent @@ -1198,6 +1218,7 @@ private List Convert(DataExporterContext ctx, NewsLetterSubscription su ExecuteContext = ctx.ExecuteContext }); + return result; } } diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs index f15c4fe3a0..c0e200ccc8 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs @@ -9,10 +9,13 @@ using SmartStore.Core; using SmartStore.Core.Domain; using SmartStore.Core.Domain.Catalog; +using SmartStore.Core.Domain.Customers; using SmartStore.Core.Domain.DataExchange; +using SmartStore.Core.Domain.Messages; using SmartStore.Core.Domain.Orders; using SmartStore.Core.Domain.Payments; using SmartStore.Core.Domain.Shipping; +using SmartStore.Core.Domain.Stores; using SmartStore.Core.Plugins; using SmartStore.Services; using SmartStore.Services.Catalog; @@ -50,6 +53,7 @@ public class ExportController : AdminControllerBase private readonly DataExchangeSettings _dataExchangeSettings; private readonly ITaskScheduler _taskScheduler; private readonly IDataExporter _dataExporter; + private readonly Lazy _customerSettings; public ExportController( ICommonServices services, @@ -65,7 +69,8 @@ public ExportController( IDateTimeHelper dateTimeHelper, DataExchangeSettings dataExchangeSettings, ITaskScheduler taskScheduler, - IDataExporter dataExporter) + IDataExporter dataExporter, + Lazy customerSettings) { _services = services; _exportService = exportService; @@ -81,6 +86,7 @@ public ExportController( _dataExchangeSettings = dataExchangeSettings; _taskScheduler = taskScheduler; _dataExporter = dataExporter; + _customerSettings = customerSettings; } #region Utilities @@ -736,7 +742,8 @@ public ActionResult Preview(int id) GridPageSize = DataExporter.PageSize, EntityType = provider.Value.EntityType, TotalRecords = totalRecords, - LogFileExists = System.IO.File.Exists(profile.GetExportLogFilePath()) + LogFileExists = System.IO.File.Exists(profile.GetExportLogFilePath()), + UsernamesEnabled = _customerSettings.Value.UsernamesEnabled }; return View(model); @@ -754,8 +761,20 @@ public ActionResult PreviewList(GridCommand command, int id, int totalRecords) { var productModel = new List(); var orderModel = new List(); + var categoryModel = new List(); + var manuModel = new List(); + var customerModel = new List(); + var subscriberModel = new List(); + + object gridData = null; + Dictionary allCategories = null; + IList allStores = null; var request = new DataExportRequest(profile, provider); + var normalizedTotal = totalRecords; + + if (profile.Limit > 0 && normalizedTotal > profile.Limit) + normalizedTotal = profile.Limit; var data = _dataExporter.Preview(request, command.Page - 1, totalRecords); @@ -764,7 +783,8 @@ public ActionResult PreviewList(GridCommand command, int id, int totalRecords) if (provider.Value.EntityType == ExportEntityType.Product) { var product = item.Entity as Product; - var pm = new ExportPreviewProductModel + + productModel.Add(new ExportPreviewProductModel { Id = product.Id, ProductTypeId = product.ProductTypeId, @@ -776,13 +796,11 @@ public ActionResult PreviewList(GridCommand command, int id, int totalRecords) Published = product.Published, StockQuantity = product.StockQuantity, AdminComment = item.AdminComment - }; - - productModel.Add(pm); + }); } else if (provider.Value.EntityType == ExportEntityType.Order) { - var om = new ExportPreviewOrderModel + orderModel.Add(new ExportPreviewOrderModel { Id = item.Id, HasNewPaymentNotification = item.HasNewPaymentNotification, @@ -794,33 +812,105 @@ public ActionResult PreviewList(GridCommand command, int id, int totalRecords) StoreName = (item.Store == null ? "".NaIfEmpty() : item.Store.Name), CreatedOn = _dateTimeHelper.ConvertToUserTime(item.CreatedOnUtc, DateTimeKind.Utc), OrderTotal = item.OrderTotal - }; + }); + } + else if (provider.Value.EntityType == ExportEntityType.Category) + { + var category = item.Entity as Category; + + if (allCategories == null) + { + allCategories = _categoryService.GetAllCategories(showHidden: true, applyNavigationFilters: false) + .ToDictionary(x => x.Id); + } - orderModel.Add(om); + categoryModel.Add(new ExportPreviewCategoryModel + { + Id = category.Id, + Breadcrumb = category.GetCategoryBreadCrumb(_categoryService, allCategories), + FullName = item.FullName, + Alias = item.Alias, + Published = category.Published, + DisplayOrder = category.DisplayOrder, + LimitedToStores = category.LimitedToStores + }); + } + else if (provider.Value.EntityType == ExportEntityType.Manufacturer) + { + manuModel.Add(new ExportPreviewManufacturerModel + { + Id = item.Id, + Name = item.Name, + Published = item.Published, + DisplayOrder = item.DisplayOrder, + LimitedToStores = item.LimitedToStores + }); } - } + else if (provider.Value.EntityType == ExportEntityType.Customer) + { + var customer = item.Entity as Customer; + var customerRoles = item.CustomerRoles as List; + var customerRolesString = string.Join(", ", customerRoles.Select(x => x.Name)); - var normalizedTotal = totalRecords; + customerModel.Add(new ExportPreviewCustomerModel + { + Id = customer.Id, + Active = customer.Active, + CreatedOn = _dateTimeHelper.ConvertToUserTime(customer.CreatedOnUtc, DateTimeKind.Utc), + CustomerRoleNames = customerRolesString, + Email = customer.Email, + FullName = item._FullName, + LastActivityDate = _dateTimeHelper.ConvertToUserTime(customer.LastActivityDateUtc, DateTimeKind.Utc), + Username = customer.Username + }); + } + else if (provider.Value.EntityType == ExportEntityType.NewsLetterSubscription) + { + var subscription = item.Entity as NewsLetterSubscription; - if (profile.Limit > 0 && normalizedTotal > profile.Limit) - normalizedTotal = profile.Limit; + if (allStores == null) + allStores = _services.StoreService.GetAllStores(); + + var store = allStores.FirstOrDefault(x => x.Id == subscription.StoreId); + + subscriberModel.Add(new ExportPreviewNewsLetterSubscriptionModel + { + Id = subscription.Id, + Active = subscription.Active, + CreatedOn = _dateTimeHelper.ConvertToUserTime(subscription.CreatedOnUtc, DateTimeKind.Utc), + Email = subscription.Email, + StoreName = (store == null ? "".NaIfEmpty() : store.Name) + }); + } + } if (provider.Value.EntityType == ExportEntityType.Product) { - return new JsonResult - { - Data = new GridModel { Data = productModel, Total = normalizedTotal } - }; + gridData = new GridModel { Data = productModel, Total = normalizedTotal }; } - - if (provider.Value.EntityType == ExportEntityType.Order) + else if (provider.Value.EntityType == ExportEntityType.Order) { - return new JsonResult - { - Data = new GridModel { Data = orderModel, Total = normalizedTotal } - }; + gridData = new GridModel { Data = orderModel, Total = normalizedTotal }; } - } + else if (provider.Value.EntityType == ExportEntityType.Category) + { + gridData = new GridModel { Data = categoryModel, Total = normalizedTotal }; + } + else if (provider.Value.EntityType == ExportEntityType.Manufacturer) + { + gridData = new GridModel { Data = manuModel, Total = normalizedTotal }; + } + else if (provider.Value.EntityType == ExportEntityType.Customer) + { + gridData = new GridModel { Data = customerModel, Total = normalizedTotal }; + } + else if (provider.Value.EntityType == ExportEntityType.NewsLetterSubscription) + { + gridData = new GridModel { Data = subscriberModel, Total = normalizedTotal }; + } + + return new JsonResult { Data = gridData }; + } return new EmptyResult(); } diff --git a/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ExportPreviewModel.cs b/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ExportPreviewModel.cs index 4dbcde6c6a..eff05703f6 100644 --- a/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ExportPreviewModel.cs +++ b/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ExportPreviewModel.cs @@ -14,6 +14,7 @@ public class ExportPreviewModel : EntityModelBase public int TotalRecords { get; set; } public ExportEntityType EntityType { get; set; } public bool LogFileExists { get; set; } + public bool UsernamesEnabled { get; set; } } public class ExportPreviewProductModel : EntityModelBase @@ -71,4 +72,81 @@ public class ExportPreviewOrderModel : EntityModelBase [SmartResourceDisplayName("Admin.Orders.Fields.OrderTotal")] public decimal OrderTotal { get; set; } } + + public class ExportPreviewCategoryModel : EntityModelBase + { + [SmartResourceDisplayName("Admin.Catalog.Products.Categories.Fields.Category")] + public string Breadcrumb { get; set; } + + [SmartResourceDisplayName("Admin.Catalog.Categories.Fields.FullName")] + public string FullName { get; set; } + + [SmartResourceDisplayName("Admin.Catalog.Categories.Fields.Alias")] + public string Alias { get; set; } + + [SmartResourceDisplayName("Admin.Catalog.Categories.Fields.Published")] + public bool Published { get; set; } + + [SmartResourceDisplayName("Admin.Catalog.Categories.Fields.DisplayOrder")] + public int DisplayOrder { get; set; } + + [SmartResourceDisplayName("Admin.Common.Store.LimitedTo")] + public bool LimitedToStores { get; set; } + } + + public class ExportPreviewManufacturerModel : EntityModelBase + { + [SmartResourceDisplayName("Admin.Catalog.Manufacturers.Fields.Name")] + public string Name { get; set; } + + [SmartResourceDisplayName("Admin.Catalog.Manufacturers.Fields.Published")] + public bool Published { get; set; } + + [SmartResourceDisplayName("Admin.Catalog.Manufacturers.Fields.DisplayOrder")] + public int DisplayOrder { get; set; } + + [SmartResourceDisplayName("Admin.Common.Store.LimitedTo")] + public bool LimitedToStores { get; set; } + } + + public class ExportPreviewCustomerModel : EntityModelBase + { + public bool UsernamesEnabled { get; set; } + + [SmartResourceDisplayName("Admin.Customers.Customers.Fields.Username")] + public string Username { get; set; } + + [SmartResourceDisplayName("Admin.Customers.Customers.Fields.FullName")] + public string FullName { get; set; } + + [SmartResourceDisplayName("Admin.Customers.Customers.Fields.Email")] + public string Email { get; set; } + + [SmartResourceDisplayName("Admin.Customers.Customers.Fields.CustomerRoles")] + public string CustomerRoleNames { get; set; } + + [SmartResourceDisplayName("Admin.Customers.Customers.Fields.Active")] + public bool Active { get; set; } + + [SmartResourceDisplayName("Admin.Customers.Customers.Fields.CreatedOn")] + public DateTime CreatedOn { get; set; } + + [SmartResourceDisplayName("Admin.Customers.Customers.Fields.LastActivityDate")] + public DateTime LastActivityDate { get; set; } + } + + public class ExportPreviewNewsLetterSubscriptionModel : EntityModelBase + { + [SmartResourceDisplayName("Admin.Promotions.NewsLetterSubscriptions.Fields.Email")] + public string Email { get; set; } + + [SmartResourceDisplayName("Admin.Promotions.NewsLetterSubscriptions.Fields.Active")] + public bool Active { get; set; } + + [SmartResourceDisplayName("Admin.Promotions.NewsLetterSubscriptions.Fields.CreatedOn")] + public DateTime CreatedOn { get; set; } + + [SmartResourceDisplayName("Admin.Common.Store")] + public string StoreName { get; set; } + } } \ No newline at end of file diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Category/List.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Category/List.cshtml index 9a3b2abd9f..08d7f81a83 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Category/List.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Category/List.cshtml @@ -65,13 +65,18 @@ columns.Bound(x => x.FullName); columns.Bound(x => x.Alias); columns.Bound(x => x.Published) - .Width(100) + .Width(160) .Template(item => @Html.SymbolForBool(item.Published)) .ClientTemplate(@Html.SymbolForBool("Published")) .Centered(); columns.Bound(x => x.DisplayOrder) - .Width(100) + .Width(160) .Centered(); + columns.Bound(x => x.LimitedToStores) + .Width(160) + .Template(item => @Html.SymbolForBool(item.LimitedToStores)) + .ClientTemplate(@Html.SymbolForBool("LimitedToStores")) + .Centered(); }) .Pageable(settings => settings.PageSize(Model.GridPageSize).Position(GridPagerPosition.Both)) .DataBinding(dataBinding => dataBinding.Ajax().Select("List", "Category")) diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Export/Preview.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Export/Preview.cshtml index 2bca030bc9..9cd9abb59e 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Export/Preview.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Export/Preview.cshtml @@ -100,81 +100,215 @@ } -@if (Model.EntityType == ExportEntityType.Product) -{ -
+
+ @if (Model.EntityType == ExportEntityType.Product) + { @(Html.Telerik().Grid() - .Name("export-grid-product") - .DataKeys(keys => keys.Add(x => x.Id) - .RouteKey("Id")) - .Columns(columns => - { - columns.Bound(x => x.Id) - .ClientTemplate("") - .Title("") - .Width(50) - .HtmlAttributes(new { style = "text-align:center" }) - .HeaderHtmlAttributes(new { style = "text-align:center" }); - columns.Bound(x => x.Id) - .Width(80) - .Centered(); - columns.Bound(x => x.Name) - .ClientTemplate(@Html.LabeledProductName("Id", "Name")); - columns.Bound(x => x.Sku); - columns.Bound(x => x.Price) - .Format("{0:0.00}") - .RightAlign(); - columns.Bound(x => x.StockQuantity) - .Centered(); - columns.Bound(x => x.Published) - .Width(100) - .ClientTemplate(@Html.SymbolForBool("Published")) - .Centered(); - columns.Bound(x => x.AdminComment); - }) - .Pageable(settings => settings.PageSize(Model.GridPageSize).Position(GridPagerPosition.Both)) - .DataBinding(dataBinding => dataBinding.Ajax().Select("PreviewList", "Export", new { id = Model.Id, totalRecords = Model.TotalRecords })) - .ClientEvents(events => events.OnDataBound("OnDataBound")) - .EnableCustomBinding(true)) -
-} -else if (Model.EntityType == ExportEntityType.Order) -{ -
+ .Name("export-grid-product") + .DataKeys(keys => keys.Add(x => x.Id) + .RouteKey("Id")) + .Columns(columns => + { + columns.Bound(x => x.Id) + .ClientTemplate("") + .Title("") + .Width(50) + .HtmlAttributes(new { style = "text-align:center" }) + .HeaderHtmlAttributes(new { style = "text-align:center" }); + columns.Bound(x => x.Id) + .Width(80) + .Centered(); + columns.Bound(x => x.Name) + .ClientTemplate(@Html.LabeledProductName("Id", "Name")); + columns.Bound(x => x.Sku); + columns.Bound(x => x.Price) + .Format("{0:0.00}") + .RightAlign(); + columns.Bound(x => x.StockQuantity) + .Centered(); + columns.Bound(x => x.Published) + .Width(160) + .ClientTemplate(@Html.SymbolForBool("Published")) + .Centered(); + columns.Bound(x => x.AdminComment); + }) + .Pageable(settings => settings.PageSize(Model.GridPageSize).Position(GridPagerPosition.Both)) + .DataBinding(dataBinding => dataBinding.Ajax().Select("PreviewList", "Export", new { id = Model.Id, totalRecords = Model.TotalRecords })) + .ClientEvents(events => events.OnDataBound("OnDataBound")) + .EnableCustomBinding(true)) + } + else if (Model.EntityType == ExportEntityType.Order) + { @(Html.Telerik().Grid() - .Name("export-grid-order") - .DataKeys(keys => keys.Add(x => x.Id) - .RouteKey("Id")) - .Columns(columns => - { - columns.Bound(x => x.Id) - .ClientTemplate("") - .Title("") - .Width(50) - .HtmlAttributes(new { style = "text-align:center" }) - .HeaderHtmlAttributes(new { style = "text-align:center" }); - columns.Bound(x => x.Id) - .Width(80) - .Centered(); - columns.Bound(x => x.OrderNumber) - .ClientTemplate(@Html.LabeledOrderNumber()); - columns.Bound(x => x.OrderStatus); - columns.Bound(x => x.PaymentStatus); - columns.Bound(x => x.ShippingStatus); - columns.Bound(x => x.CustomerEmail); - columns.Bound(x => x.StoreName); - columns.Bound(x => x.CreatedOn); - columns.Bound(x => x.OrderTotal) - .Format("{0:0.00}") - .RightAlign(); - }) - .Pageable(settings => settings.PageSize(Model.GridPageSize).Position(GridPagerPosition.Both)) - .DataBinding(dataBinding => dataBinding.Ajax().Select("PreviewList", "Export", new { id = Model.Id, totalRecords = Model.TotalRecords })) - .ClientEvents(events => events.OnDataBound("OnDataBound")) - .EnableCustomBinding(true)) -
-} -else -{ -
@T("Admin.DataExchange.Export.NoPreview")
-} \ No newline at end of file + .Name("export-grid-order") + .DataKeys(keys => keys.Add(x => x.Id) + .RouteKey("Id")) + .Columns(columns => + { + columns.Bound(x => x.Id) + .ClientTemplate("") + .Title("") + .Width(50) + .HtmlAttributes(new { style = "text-align:center" }) + .HeaderHtmlAttributes(new { style = "text-align:center" }); + columns.Bound(x => x.Id) + .Width(80) + .Centered(); + columns.Bound(x => x.OrderNumber) + .ClientTemplate(@Html.LabeledOrderNumber()); + columns.Bound(x => x.OrderStatus); + columns.Bound(x => x.PaymentStatus); + columns.Bound(x => x.ShippingStatus); + columns.Bound(x => x.CustomerEmail); + columns.Bound(x => x.StoreName); + columns.Bound(x => x.CreatedOn); + columns.Bound(x => x.OrderTotal) + .Format("{0:0.00}") + .RightAlign(); + }) + .Pageable(settings => settings.PageSize(Model.GridPageSize).Position(GridPagerPosition.Both)) + .DataBinding(dataBinding => dataBinding.Ajax().Select("PreviewList", "Export", new { id = Model.Id, totalRecords = Model.TotalRecords })) + .ClientEvents(events => events.OnDataBound("OnDataBound")) + .EnableCustomBinding(true)) + } + else if (Model.EntityType == ExportEntityType.Category) + { + @(Html.Telerik().Grid() + .Name("export-grid-order") + .DataKeys(keys => keys.Add(x => x.Id) + .RouteKey("Id")) + .Columns(columns => + { + columns.Bound(x => x.Id) + .ClientTemplate("") + .Title("") + .Width(50) + .HtmlAttributes(new { style = "text-align:center" }) + .HeaderHtmlAttributes(new { style = "text-align:center" }); + columns.Bound(x => x.Id) + .Width(80) + .Centered(); + columns.Bound(x => x.Breadcrumb); + columns.Bound(x => x.FullName); + columns.Bound(x => x.Alias); + columns.Bound(x => x.Published) + .Width(160) + .ClientTemplate(@Html.SymbolForBool("Published")) + .Centered(); + columns.Bound(x => x.DisplayOrder) + .Width(160) + .Centered(); + columns.Bound(x => x.LimitedToStores) + .Width(160) + .ClientTemplate(@Html.SymbolForBool("LimitedToStores")) + .Centered(); + }) + .Pageable(settings => settings.PageSize(Model.GridPageSize).Position(GridPagerPosition.Both)) + .DataBinding(dataBinding => dataBinding.Ajax().Select("PreviewList", "Export", new { id = Model.Id, totalRecords = Model.TotalRecords })) + .ClientEvents(events => events.OnDataBound("OnDataBound")) + .EnableCustomBinding(true)) + } + else if (Model.EntityType == ExportEntityType.Manufacturer) + { + @(Html.Telerik().Grid() + .Name("export-grid-order") + .DataKeys(keys => keys.Add(x => x.Id) + .RouteKey("Id")) + .Columns(columns => + { + columns.Bound(x => x.Id) + .ClientTemplate("") + .Title("") + .Width(50) + .HtmlAttributes(new { style = "text-align:center" }) + .HeaderHtmlAttributes(new { style = "text-align:center" }); + columns.Bound(x => x.Id) + .Width(80) + .Centered(); + columns.Bound(x => x.Name); + columns.Bound(x => x.Published) + .Width(160) + .ClientTemplate(@Html.SymbolForBool("Published")) + .Centered(); + columns.Bound(x => x.DisplayOrder) + .Width(160) + .Centered(); + columns.Bound(x => x.LimitedToStores) + .Width(160) + .ClientTemplate(@Html.SymbolForBool("LimitedToStores")) + .Centered(); + }) + .Pageable(settings => settings.PageSize(Model.GridPageSize).Position(GridPagerPosition.Both)) + .DataBinding(dataBinding => dataBinding.Ajax().Select("PreviewList", "Export", new { id = Model.Id, totalRecords = Model.TotalRecords })) + .ClientEvents(events => events.OnDataBound("OnDataBound")) + .EnableCustomBinding(true)) + } + else if (Model.EntityType == ExportEntityType.Customer) + { + @(Html.Telerik().Grid() + .Name("export-grid-order") + .DataKeys(keys => keys.Add(x => x.Id) + .RouteKey("Id")) + .Columns(columns => + { + columns.Bound(x => x.Id) + .ClientTemplate("") + .Title("") + .Width(50) + .HtmlAttributes(new { style = "text-align:center" }) + .HeaderHtmlAttributes(new { style = "text-align:center" }); + columns.Bound(x => x.Id) + .Width(80) + .Centered(); + columns.Bound(x => x.Email); + columns.Bound(x => x.Username) + .Visible(Model.UsernamesEnabled); + columns.Bound(x => x.FullName); + columns.Bound(x => x.CustomerRoleNames); + columns.Bound(x => x.Active) + .ClientTemplate(@Html.SymbolForBool("Active")) + .Width(160) + .Centered(); + columns.Bound(x => x.CreatedOn); + columns.Bound(x => x.LastActivityDate); + }) + .Pageable(settings => settings.PageSize(Model.GridPageSize).Position(GridPagerPosition.Both)) + .DataBinding(dataBinding => dataBinding.Ajax().Select("PreviewList", "Export", new { id = Model.Id, totalRecords = Model.TotalRecords })) + .ClientEvents(events => events.OnDataBound("OnDataBound")) + .EnableCustomBinding(true)) + } + else if (Model.EntityType == ExportEntityType.NewsLetterSubscription) + { + @(Html.Telerik().Grid() + .Name("export-grid-order") + .DataKeys(keys => keys.Add(x => x.Id) + .RouteKey("Id")) + .Columns(columns => + { + columns.Bound(x => x.Id) + .ClientTemplate("") + .Title("") + .Width(50) + .HtmlAttributes(new { style = "text-align:center" }) + .HeaderHtmlAttributes(new { style = "text-align:center" }); + columns.Bound(x => x.Id) + .Width(80) + .Centered(); + columns.Bound(x => x.Email); + columns.Bound(x => x.Active) + .ClientTemplate(@Html.SymbolForBool("Active")) + .Centered() + .Width(160); + columns.Bound(x => x.StoreName); + columns.Bound(x => x.CreatedOn); + }) + .Pageable(settings => settings.PageSize(Model.GridPageSize).Position(GridPagerPosition.Both)) + .DataBinding(dataBinding => dataBinding.Ajax().Select("PreviewList", "Export", new { id = Model.Id, totalRecords = Model.TotalRecords })) + .ClientEvents(events => events.OnDataBound("OnDataBound")) + .EnableCustomBinding(true)) + } + else + { +
@T("Admin.DataExchange.Export.NoPreview")
+ } +
\ No newline at end of file diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Manufacturer/List.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Manufacturer/List.cshtml index 87310a67ee..be3c64facb 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Manufacturer/List.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Manufacturer/List.cshtml @@ -40,45 +40,43 @@ +

+
@(Html.Telerik().Grid(Model.Manufacturers.Data) - .Name("manufacturers-grid") - .ClientEvents(events => events - .OnDataBinding("onDataBinding")) - .Columns(columns => - { - columns.Bound(x => x.Name).Width(300) - .Template(x => Html.ActionLink(x.Name, "Edit", new { id = x.Id })) - .ClientTemplate("\"><#= Name #>"); - - // .Template(x => Html.ActionLink(x.Name, "Edit", new { id = x.Id })) - //.ClientTemplate("'><#= Name #>"); - - columns.Bound(x => x.Published) - .Width(100) - .Template(item => @Html.SymbolForBool(item.Published)) - .ClientTemplate(@Html.SymbolForBool("Published")) - .Centered(); - columns.Bound(x => x.DisplayOrder) - .Width(100) - .Centered(); - columns.Bound(x => x.Id) - .Width(50) - .Centered() - .Template(x => Html.ActionLink(T("Admin.Common.Edit").Text, "Edit", new { id = x.Id })) - .ClientTemplate("\">" + T("Admin.Common.Edit").Text + "") - .Title(T("Admin.Common.Edit").Text); - }) - .Pageable(settings => settings.Total(Model.Manufacturers.Total).PageSize(gridPageSize).Position(GridPagerPosition.Both)) - .DataBinding(dataBinding => dataBinding.Ajax().Select("List", "Manufacturer")) + .Name("manufacturers-grid") + .ClientEvents(events => events + .OnDataBinding("onDataBinding")) + .Columns(columns => + { + columns.Bound(x => x.Name) + .Template(x => Html.ActionLink(x.Name, "Edit", new { id = x.Id })) + .ClientTemplate("\"><#= Name #>"); + columns.Bound(x => x.Published) + .Width(160) + .Template(item => @Html.SymbolForBool(item.Published)) + .ClientTemplate(@Html.SymbolForBool("Published")) + .Centered(); + columns.Bound(x => x.DisplayOrder) + .Width(160) + .Centered(); + columns.Bound(x => x.LimitedToStores) + .Width(160) + .Template(item => @Html.SymbolForBool(item.LimitedToStores)) + .ClientTemplate(@Html.SymbolForBool("LimitedToStores")) + .Centered(); + }) + .Pageable(settings => settings.Total(Model.Manufacturers.Total).PageSize(gridPageSize).Position(GridPagerPosition.Both)) + .DataBinding(dataBinding => dataBinding.Ajax().Select("List", "Manufacturer")) .PreserveGridState() - .EnableCustomBinding(true)) + .EnableCustomBinding(true))
+ From afce7e6f3eac3cf6ae6b47a0cb774333be42f0be Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Tue, 17 Nov 2015 10:42:22 +0100 Subject: [PATCH 033/626] Minor changes --- .../Data/IDbContextExtensions.cs | 28 --------- .../SmartStore.Data/ObjectContextBase.cs | 60 +++++++++++-------- .../DataExchange/DataExporter.cs | 45 +++++++++----- .../Deployment/EmailFilePublisher.cs | 14 +++-- .../Deployment/FileSystemFilePublisher.cs | 9 --- .../Deployment/FtpFilePublisher.cs | 9 --- .../Deployment/HttpFilePublisher.cs | 8 --- .../DataExchange/Deployment/IFilePublisher.cs | 3 - .../DataExchange/DynamicEntityHelper.cs | 25 +++----- .../Internal/DataExporterContext.cs | 10 +--- 10 files changed, 79 insertions(+), 132 deletions(-) diff --git a/src/Libraries/SmartStore.Core/Data/IDbContextExtensions.cs b/src/Libraries/SmartStore.Core/Data/IDbContextExtensions.cs index 0bc3d4dc7f..0889cd6684 100644 --- a/src/Libraries/SmartStore.Core/Data/IDbContextExtensions.cs +++ b/src/Libraries/SmartStore.Core/Data/IDbContextExtensions.cs @@ -28,34 +28,6 @@ public static void DetachEntities(this IDbContext ctx, IEnumerable ctx.DetachEntity(x)); } - public static void Attach(this IDbContext ctx, TEntity entity) where TEntity : BaseEntity - { - var dbSet = ctx.Set(); - var alreadyAttached = dbSet.Local.FirstOrDefault(x => x.Id == entity.Id); - - if (alreadyAttached == null) - { - dbSet.Attach(entity); - } - } - - public static void Attach(this IDbContext ctx, IEnumerable entities) where TEntity : BaseEntity - { - Guard.ArgumentNotNull(() => ctx); - - var dbSet = ctx.Set(); - - entities.Each(entity => - { - var alreadyAttached = dbSet.Local.FirstOrDefault(x => x.Id == entity.Id); - - if (alreadyAttached == null) - { - dbSet.Attach(entity); - } - }); - } - /// /// Changes the object state to unchanged /// diff --git a/src/Libraries/SmartStore.Data/ObjectContextBase.cs b/src/Libraries/SmartStore.Data/ObjectContextBase.cs index 5f722e155f..278d88d984 100644 --- a/src/Libraries/SmartStore.Data/ObjectContextBase.cs +++ b/src/Libraries/SmartStore.Data/ObjectContextBase.cs @@ -2,27 +2,26 @@ using System.Collections.Generic; using System.Data; using System.Data.Common; -using System.Data.SqlClient; using System.Data.Entity; using System.Data.Entity.Infrastructure; using System.Data.Entity.Validation; +using System.Data.SqlClient; using System.Linq; -using System.Linq.Expressions; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; +using Microsoft.SqlServer.Management.Common; +using Microsoft.SqlServer.Management.Smo; using SmartStore.Core; using SmartStore.Core.Data; using SmartStore.Core.Data.Hooks; -using Microsoft.SqlServer.Management.Common; -using Microsoft.SqlServer.Management.Smo; using SmartStore.Core.Events; namespace SmartStore.Data { - /// - /// Object context - /// + /// + /// Object context + /// [DbConfigurationType(typeof(SmartDbConfiguration))] public abstract class ObjectContextBase : DbContext, IDbContext { @@ -496,32 +495,41 @@ protected internal bool IsSqlServer2012OrHigher() return s_isSqlServer2012OrHigher.Value; } - /// - /// Attach an entity to the context or return an already attached entity (if it was already attached) - /// - /// TEntity - /// Entity - /// Attached entity - protected virtual TEntity AttachEntity(TEntity entity) where TEntity : BaseEntity, new() - { - // little hack here until Entity Framework really supports stored procedures - // otherwise, navigation properties of loaded entities are not loaded until an entity is attached to the context - var dbSet = Set(); - var alreadyAttached = dbSet.Local.Where(x => x.Id == entity.Id).FirstOrDefault(); + private TEntity Attach(DbSet dbSet, TEntity entity) where TEntity : BaseEntity + { + var alreadyAttached = dbSet.Local.FirstOrDefault(x => x.Id == entity.Id); + if (alreadyAttached == null) { - // attach new entity dbSet.Attach(entity); return entity; } - else - { - // entity is already loaded. - return alreadyAttached; - } + + return alreadyAttached; + } + + /// + /// Attach an entity to the context or return an already attached entity (if it was already attached) + /// + /// TEntity + /// Entity + /// Attached entity + public TEntity AttachEntity(TEntity entity) where TEntity : BaseEntity + { + // little hack here until Entity Framework really supports stored procedures + // otherwise, navigation properties of loaded entities are not loaded until an entity is attached to the context + + return Attach(Set(), entity); } - public bool IsAttached(TEntity entity) where TEntity : BaseEntity + public void AttachEntities(IEnumerable entities) where TEntity : BaseEntity + { + var dbSet = Set(); + + entities.Each(entity => Attach(dbSet, entity)); + } + + public bool IsAttached(TEntity entity) where TEntity : BaseEntity { if (entity != null) { diff --git a/src/Libraries/SmartStore.Services/DataExchange/DataExporter.cs b/src/Libraries/SmartStore.Services/DataExchange/DataExporter.cs index 3ccd178409..1fb126c0de 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/DataExporter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/DataExporter.cs @@ -19,6 +19,7 @@ using SmartStore.Core.Infrastructure; using SmartStore.Core.Localization; using SmartStore.Core.Logging; +using SmartStore.Data; using SmartStore.Services.Catalog; using SmartStore.Services.Common; using SmartStore.Services.Customers; @@ -69,10 +70,10 @@ public partial class DataExporter : IDataExporter private readonly Lazy _shipmentService; private readonly Lazy _genericAttributeService; private readonly Lazy _emailAccountService; + private readonly Lazy _queuedEmailService; private readonly Lazy _emailSender; private readonly Lazy _deliveryTimeService; private readonly Lazy _quantityUnitService; - private readonly Lazy _typeFinder; private readonly Lazy>_customerRepository; private readonly Lazy> _subscriptionRepository; @@ -107,10 +108,10 @@ public DataExporter( Lazy shipmentService, Lazy genericAttributeService, Lazy emailAccountService, - Lazy emailSender, + Lazy queuedEmailService, + Lazy emailSender, Lazy deliveryTimeService, Lazy quantityUnitService, - Lazy typeFinder, Lazy> customerRepository, Lazy> subscriptionRepository, Lazy> orderRepository, @@ -142,10 +143,10 @@ public DataExporter( _shipmentService = shipmentService; _genericAttributeService = genericAttributeService; _emailAccountService = emailAccountService; + _queuedEmailService = queuedEmailService; _emailSender = emailSender; _deliveryTimeService = deliveryTimeService; _quantityUnitService = quantityUnitService; - _typeFinder = typeFinder; _customerRepository = customerRepository; _subscriptionRepository = subscriptionRepository; @@ -210,10 +211,11 @@ private void DetachAllEntitiesAndClear(DataExporterContext ctx) try { // now again attach what is globally required + var dataContextBase = _dbContext as ObjectContextBase; - _dbContext.Attach(ctx.Request.Profile); + dataContextBase.AttachEntity(ctx.Request.Profile); - _dbContext.Attach(ctx.Stores.Values); + dataContextBase.AttachEntities(ctx.Stores.Values); } catch (Exception exception) { @@ -421,10 +423,6 @@ private void Deploy(DataExporterContext ctx) var containerManager = EngineContext.Current.ContainerManager; var allFiles = System.IO.Directory.GetFiles(ctx.FolderContent, "*.*", SearchOption.AllDirectories); - var publishers = _typeFinder.Value.FindClassesOfType(ignoreInactivePlugins: true) - .Select(x => containerManager.ResolveUnregistered(x) as IFilePublisher) - .ToList(); - var context = new ExportDeploymentContext { Log = ctx.Log, @@ -439,17 +437,33 @@ private void Deploy(DataExporterContext ctx) else context.DeploymentFiles = allFiles; - foreach (var publisher in publishers.Where(x => x.DeploymentType == deployment.DeploymentType)) + try { - try + if (deployment.DeploymentType == ExportDeploymentType.Email) { + var publisher = new EmailFilePublisher(_emailAccountService.Value, _queuedEmailService.Value); publisher.Publish(context, deployment); } - catch (Exception exception) + else if (deployment.DeploymentType == ExportDeploymentType.FileSystem) { - ctx.Log.Error("Deployment \"{0}\" of type {1} failed: {2}".FormatInvariant( - deployment.Name, deployment.DeploymentType.ToString(), exception.Message), exception); + var publisher = new FileSystemFilePublisher(); + publisher.Publish(context, deployment); + } + else if (deployment.DeploymentType == ExportDeploymentType.Ftp) + { + var publisher = new FtpFilePublisher(); + publisher.Publish(context, deployment); } + else if (deployment.DeploymentType == ExportDeploymentType.Http) + { + var publisher = new HttpFilePublisher(); + publisher.Publish(context, deployment); + } + } + catch (Exception exception) + { + ctx.Log.Error("Deployment \"{0}\" of type {1} failed: {2}".FormatInvariant( + deployment.Name, deployment.DeploymentType.ToString(), exception.Message), exception); } } } @@ -1096,7 +1110,6 @@ private void ExportCoreOuter(DataExporterContext ctx) ctx.DeliveryTimes.Clear(); ctx.CategoryPathes.Clear(); ctx.Categories.Clear(); - ctx.PropertiesCache.Clear(); ctx.Request.CustomData.Clear(); diff --git a/src/Libraries/SmartStore.Services/DataExchange/Deployment/EmailFilePublisher.cs b/src/Libraries/SmartStore.Services/DataExchange/Deployment/EmailFilePublisher.cs index bc9903e734..d6ee4b4f2c 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Deployment/EmailFilePublisher.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Deployment/EmailFilePublisher.cs @@ -2,7 +2,6 @@ using System.IO; using System.Linq; using SmartStore.Core.Domain; -using SmartStore.Core.Domain.DataExchange; using SmartStore.Core.Domain.Messages; using SmartStore.Core.Email; using SmartStore.Core.Infrastructure; @@ -14,12 +13,15 @@ namespace SmartStore.Services.DataExchange.Deployment { public class EmailFilePublisher : IFilePublisher { - public ExportDeploymentType DeploymentType + private IEmailAccountService _emailAccountService; + private IQueuedEmailService _queuedEmailService; + + public EmailFilePublisher( + IEmailAccountService emailAccountService, + IQueuedEmailService queuedEmailService) { - get - { - return ExportDeploymentType.Email; - } + _emailAccountService = emailAccountService; + _queuedEmailService = queuedEmailService; } public virtual void Publish(ExportDeploymentContext context, ExportDeployment deployment) diff --git a/src/Libraries/SmartStore.Services/DataExchange/Deployment/FileSystemFilePublisher.cs b/src/Libraries/SmartStore.Services/DataExchange/Deployment/FileSystemFilePublisher.cs index 392ab82680..2fba5924a0 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Deployment/FileSystemFilePublisher.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Deployment/FileSystemFilePublisher.cs @@ -1,7 +1,6 @@ using System.IO; using System.Web; using SmartStore.Core.Domain; -using SmartStore.Core.Domain.DataExchange; using SmartStore.Core.Logging; using SmartStore.Utilities; @@ -9,14 +8,6 @@ namespace SmartStore.Services.DataExchange.Deployment { public class FileSystemFilePublisher : IFilePublisher { - public ExportDeploymentType DeploymentType - { - get - { - return ExportDeploymentType.FileSystem; - } - } - public virtual void Publish(ExportDeploymentContext context, ExportDeployment deployment) { string folderDestination = null; diff --git a/src/Libraries/SmartStore.Services/DataExchange/Deployment/FtpFilePublisher.cs b/src/Libraries/SmartStore.Services/DataExchange/Deployment/FtpFilePublisher.cs index 4fad3cc146..bba604f38a 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Deployment/FtpFilePublisher.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Deployment/FtpFilePublisher.cs @@ -3,21 +3,12 @@ using System.Linq; using System.Net; using SmartStore.Core.Domain; -using SmartStore.Core.Domain.DataExchange; using SmartStore.Core.Logging; namespace SmartStore.Services.DataExchange.Deployment { public class FtpFilePublisher : IFilePublisher { - public ExportDeploymentType DeploymentType - { - get - { - return ExportDeploymentType.Ftp; - } - } - public virtual void Publish(ExportDeploymentContext context, ExportDeployment deployment) { var bytesRead = 0; diff --git a/src/Libraries/SmartStore.Services/DataExchange/Deployment/HttpFilePublisher.cs b/src/Libraries/SmartStore.Services/DataExchange/Deployment/HttpFilePublisher.cs index fadcf8a8d3..b2ab9001cb 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Deployment/HttpFilePublisher.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Deployment/HttpFilePublisher.cs @@ -10,14 +10,6 @@ namespace SmartStore.Services.DataExchange.Deployment { public class HttpFilePublisher : IFilePublisher { - public ExportDeploymentType DeploymentType - { - get - { - return ExportDeploymentType.Http; - } - } - public virtual void Publish(ExportDeploymentContext context, ExportDeployment deployment) { var succeeded = 0; diff --git a/src/Libraries/SmartStore.Services/DataExchange/Deployment/IFilePublisher.cs b/src/Libraries/SmartStore.Services/DataExchange/Deployment/IFilePublisher.cs index 9f13724efb..36b9d7eb6a 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Deployment/IFilePublisher.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Deployment/IFilePublisher.cs @@ -1,13 +1,10 @@ using SmartStore.Core.Domain; -using SmartStore.Core.Domain.DataExchange; using SmartStore.Core.Logging; namespace SmartStore.Services.DataExchange.Deployment { public interface IFilePublisher { - ExportDeploymentType DeploymentType { get; } - void Publish(ExportDeploymentContext context, ExportDeployment deployment); } diff --git a/src/Libraries/SmartStore.Services/DataExchange/DynamicEntityHelper.cs b/src/Libraries/SmartStore.Services/DataExchange/DynamicEntityHelper.cs index a007c8763e..f88aa7cda1 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/DynamicEntityHelper.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/DynamicEntityHelper.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.ComponentModel.DataAnnotations.Schema; using System.Linq; using System.Linq.Expressions; using System.Reflection; @@ -26,6 +25,7 @@ using SmartStore.Services.DataExchange.Internal; using SmartStore.Services.Localization; using SmartStore.Services.Seo; +using SmartStore.Utilities.Reflection; namespace SmartStore.Services.DataExchange { @@ -953,28 +953,17 @@ private List Convert(DataExporterContext ctx, Product product) if (!ctx.IsPreview && ctx.Projection.AttributeCombinationAsProduct && combinations.Where(x => x.IsActive).Count() > 0) { var productType = typeof(Product); - IEnumerable properties = null; var productValues = new Dictionary(); - // fetch all cloneable product properties once per export - if (ctx.PropertiesCache.ContainsKey(productType)) - { - properties = ctx.PropertiesCache[productType]; - } - else - { - properties = productType - .GetProperties() - .Where(x => x.CanRead && x.CanWrite && 0 == x.GetCustomAttributes(typeof(NotMappedAttribute), true).Length); - - ctx.PropertiesCache.Add(productType, properties); - } + var properties = FastProperty.GetProperties(product.GetUnproxiedType()) + .Values + .Where(x => x.Property.CanRead && x.Property.CanWrite); // fetch all property values once per product foreach (var property in properties) { - productValues.Add(property.Name, property.GetValue(product, null)); - } + productValues.Add(property.Name, property.GetValue(product)); + } foreach (var combination in combinations.Where(x => x.IsActive)) { @@ -982,7 +971,7 @@ private List Convert(DataExporterContext ctx, Product product) foreach (var property in properties) { - property.SetValue(productClone, productValues[property.Name], null); + property.SetValue(productClone, productValues[property.Name]); } var dynObject = ToDynamic(ctx, productClone, combinations, combination); diff --git a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporterContext.cs b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporterContext.cs index 6dbaf059d4..0d44c9843e 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporterContext.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporterContext.cs @@ -1,8 +1,6 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.IO; using System.Linq; -using System.Reflection; using System.Threading; using SmartStore.Core; using SmartStore.Core.Domain.Catalog; @@ -41,7 +39,6 @@ public DataExporterContext( RecordsPerStore = new Dictionary(); EntityIdsLoaded = new List(); EntityIdsPerSegment = new List(); - PropertiesCache = new Dictionary>(); Result = new DataExportResult { @@ -69,11 +66,6 @@ public void SetLoadedEntityIds(IEnumerable ids) /// public List EntityIdsPerSegment { get; set; } - /// - /// For faster reflection - /// - public Dictionary> PropertiesCache { get; set; } - public int RecordCount { get; set; } public Dictionary RecordsPerStore { get; set; } public string ProgressInfo { get; set; } From 7883c7c7f607a37f164281ebeeeff2c258fa5384 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Tue, 17 Nov 2015 11:43:36 +0100 Subject: [PATCH 034/626] Removed necessity of handling with volatile export profiles --- .../DataExchange/ExportProfileService.cs | 38 +++++-------------- .../DataExchange/IExportProfileService.cs | 7 ---- .../Controllers/ExportController.cs | 2 +- 3 files changed, 11 insertions(+), 36 deletions(-) diff --git a/src/Libraries/SmartStore.Services/DataExchange/ExportProfileService.cs b/src/Libraries/SmartStore.Services/DataExchange/ExportProfileService.cs index faa5dcefb5..df8f6b6832 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/ExportProfileService.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/ExportProfileService.cs @@ -47,32 +47,6 @@ public ExportProfileService( #region Export profiles - public virtual ExportProfile CreateVolatileProfile(Provider provider) - { - var name = provider.GetName(_localizationService); - var seoName = SeoHelper.GetSeName(name, true, false).Replace("/", "").Replace("-", ""); - - var profile = new ExportProfile - { - Id = 0, - Name = name, - FolderName = seoName.ToValidPath().Truncate(_dataExchangeSettings.MaxFileNameLength), - FileNamePattern = _defaultFileNamePattern, - ProviderSystemName = provider.Metadata.SystemName, - Enabled = true, - SchedulingTaskId = 0, - PerStore = false, - CreateZipArchive = false, - Cleanup = false, - ScheduleTask = null, // volatile schedule task impossible cause of database accesses by core - Deployments = new List() - }; - - // profile.Projection and profile.Filtering should be null here - - return profile; - } - public virtual ExportProfile InsertExportProfile( string providerSystemName, string name, @@ -90,7 +64,6 @@ public virtual ExportProfile InsertExportProfile( ScheduleTask task = null; ExportProfile profile = null; - var seoName = SeoHelper.GetSeName(name, true, false).Replace("/", "").Replace("-", ""); if (cloneProfile == null) { @@ -155,10 +128,19 @@ public virtual ExportProfile InsertExportProfile( profile.IsSystemProfile = isSystemProfile; profile.Name = name; - profile.FolderName = seoName.ToValidPath().Truncate(_dataExchangeSettings.MaxFileNameLength); profile.ProviderSystemName = providerSystemName; profile.SchedulingTaskId = task.Id; + var folderName = providerSystemName + .Replace("Exports.", "") + .Replace("Feeds.", "") + .Replace("/", "") + .Replace("-", ""); + + profile.FolderName = SeoHelper.GetSeName(folderName, true, false) + .ToValidPath() + .Truncate(_dataExchangeSettings.MaxFileNameLength); + _exportProfileRepository.Insert(profile); task.Alias = profile.Id.ToString(); diff --git a/src/Libraries/SmartStore.Services/DataExchange/IExportProfileService.cs b/src/Libraries/SmartStore.Services/DataExchange/IExportProfileService.cs index 4e583b38f2..27b353d532 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/IExportProfileService.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/IExportProfileService.cs @@ -8,13 +8,6 @@ namespace SmartStore.Services.DataExchange { public interface IExportProfileService { - /// - /// Creates a volatile export profile - /// - /// Export provider - /// New export profile - ExportProfile CreateVolatileProfile(Provider provider); - /// /// Inserts an export profile /// diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs index ce5494ab60..5fafb8d0df 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs @@ -460,7 +460,7 @@ public ActionResult List() if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageExports)) return AccessDeniedView(); - var providers = _exportService.LoadAllExportProviders().ToList(); + var providers = _exportService.LoadAllExportProviders(0, false).ToList(); var profiles = _exportService.GetExportProfiles().ToList(); var model = new List(); From a1428df101e727e4865e29680e1798c4aed5e682 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Tue, 17 Nov 2015 12:06:42 +0100 Subject: [PATCH 035/626] Added new permission record "ManageUrlRecords" --- .../Migrations/201511121139009_ExportFramework3.cs | 12 ++++++++++++ .../Security/StandardPermissionProvider.cs | 10 ++++++---- .../Controllers/UrlRecordController.cs | 13 ++++++------- 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/Libraries/SmartStore.Data/Migrations/201511121139009_ExportFramework3.cs b/src/Libraries/SmartStore.Data/Migrations/201511121139009_ExportFramework3.cs index b35af29179..093398f968 100644 --- a/src/Libraries/SmartStore.Data/Migrations/201511121139009_ExportFramework3.cs +++ b/src/Libraries/SmartStore.Data/Migrations/201511121139009_ExportFramework3.cs @@ -7,6 +7,8 @@ namespace SmartStore.Data.Migrations using Core.Domain; using System.Linq; using Utilities; + using Core.Domain.Security; + using Core.Domain.Customers; public partial class ExportFramework3 : DbMigration, ILocaleResourcesProvider, IDataSeeder { @@ -31,6 +33,16 @@ public void Seed(SmartObjectContext context) { context.MigrateLocaleResources(MigrateLocaleResources); + var permissionMigrator = new PermissionMigrator(context); + + permissionMigrator.AddPermission(new PermissionRecord + { + Name = "Admin area. Manage Url Records", + SystemName = "ManageUrlRecords", + Category = "Standard" + }, new string[] { SystemCustomerRoleNames.Administrators }); + + var systemProfilesInfos = new List { new SystemProfileInfo { SystemName = "SmartStoreCategoryXml", ProviderSystemName = "Exports.SmartStoreCategoryXml", Name = "Category XML Export" }, diff --git a/src/Libraries/SmartStore.Services/Security/StandardPermissionProvider.cs b/src/Libraries/SmartStore.Services/Security/StandardPermissionProvider.cs index 7018c51146..4f37e81bb0 100644 --- a/src/Libraries/SmartStore.Services/Security/StandardPermissionProvider.cs +++ b/src/Libraries/SmartStore.Services/Security/StandardPermissionProvider.cs @@ -50,10 +50,10 @@ public partial class StandardPermissionProvider : IPermissionProvider public static readonly PermissionRecord UploadPictures = new PermissionRecord { Name = "Admin area. Upload Pictures", SystemName = "UploadPictures", Category = "Configuration" }; public static readonly PermissionRecord ManageScheduleTasks = new PermissionRecord { Name = "Admin area. Manage Schedule Tasks", SystemName = "ManageScheduleTasks", Category = "Configuration" }; public static readonly PermissionRecord ManageExports = new PermissionRecord { Name = "Admin area. Manage Exports", SystemName = "ManageExports", Category = "Configuration" }; + public static readonly PermissionRecord ManageUrlRecords = new PermissionRecord { Name = "Admin area. Manage Url Records", SystemName = "ManageUrlRecords", Category = "Standard" }; - - //public store permissions - public static readonly PermissionRecord DisplayPrices = new PermissionRecord { Name = "Public store. Display Prices", SystemName = "DisplayPrices", Category = "PublicStore" }; + //public store permissions + public static readonly PermissionRecord DisplayPrices = new PermissionRecord { Name = "Public store. Display Prices", SystemName = "DisplayPrices", Category = "PublicStore" }; public static readonly PermissionRecord EnableShoppingCart = new PermissionRecord { Name = "Public store. Enable shopping cart", SystemName = "EnableShoppingCart", Category = "PublicStore" }; public static readonly PermissionRecord EnableWishlist = new PermissionRecord { Name = "Public store. Enable wishlist", SystemName = "EnableWishlist", Category = "PublicStore" }; public static readonly PermissionRecord PublicStoreAllowNavigation = new PermissionRecord { Name = "Public store. Allow navigation", SystemName = "PublicStoreAllowNavigation", Category = "PublicStore" }; @@ -105,7 +105,8 @@ public virtual IEnumerable GetPermissions() UploadPictures, ManageScheduleTasks, ManageExports, - DisplayPrices, + ManageUrlRecords, + DisplayPrices, EnableShoppingCart, EnableWishlist, PublicStoreAllowNavigation, @@ -163,6 +164,7 @@ public virtual IEnumerable GetDefaultPermissions() UploadPictures, ManageScheduleTasks, ManageExports, + ManageUrlRecords, DisplayPrices, EnableShoppingCart, EnableWishlist, diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/UrlRecordController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/UrlRecordController.cs index 1eb07d10a5..358b174f27 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/UrlRecordController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/UrlRecordController.cs @@ -14,7 +14,6 @@ namespace SmartStore.Admin.Controllers { - // TODO: add new permisssion record "ManageUrlRecords" [AdminAuthorize] public class UrlRecordController : AdminControllerBase { @@ -82,7 +81,7 @@ private void PrepareUrlRecordModel(UrlRecordModel model, UrlRecord urlRecord, bo public ActionResult List(string entityName, int? entityId) { - if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageMaintenance)) + if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageUrlRecords)) return AccessDeniedView(); var model = new UrlRecordListModel @@ -106,7 +105,7 @@ public ActionResult List(string entityName, int? entityId) [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult List(GridCommand command, UrlRecordListModel model) { - if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageMaintenance)) + if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageUrlRecords)) return AccessDeniedView(); var allLanguages = _languageService.GetAllLanguages(true); @@ -152,7 +151,7 @@ public ActionResult List(GridCommand command, UrlRecordListModel model) public ActionResult Edit(int id) { - if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageMaintenance)) + if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageUrlRecords)) return AccessDeniedView(); var urlRecord = _urlRecordService.GetUrlRecordById(id); @@ -168,7 +167,7 @@ public ActionResult Edit(int id) [HttpPost, ParameterBasedOnFormNameAttribute("save-continue", "continueEditing")] public ActionResult Edit(UrlRecordModel model, bool continueEditing) { - if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageMaintenance)) + if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageUrlRecords)) return AccessDeniedView(); var urlRecord = _urlRecordService.GetUrlRecordById(model.Id); @@ -206,7 +205,7 @@ public ActionResult Edit(UrlRecordModel model, bool continueEditing) [HttpPost, ActionName("Delete")] public ActionResult DeleteConfirmed(int id) { - if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageMaintenance)) + if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageUrlRecords)) return AccessDeniedView(); var urlRecord = _urlRecordService.GetUrlRecordById(id); @@ -231,7 +230,7 @@ public ActionResult DeleteConfirmed(int id) [HttpPost] public ActionResult DeleteSelected(ICollection selectedIds) { - if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageMaintenance)) + if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageUrlRecords)) return AccessDeniedView(); if (selectedIds != null) From 2d81510e80dff032894a7eaefd4dd1e5ad94f38f Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Tue, 17 Nov 2015 12:09:19 +0100 Subject: [PATCH 036/626] Minor change --- .../Migrations/201511121139009_ExportFramework3.cs | 2 +- .../SmartStore.Services/Security/StandardPermissionProvider.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Libraries/SmartStore.Data/Migrations/201511121139009_ExportFramework3.cs b/src/Libraries/SmartStore.Data/Migrations/201511121139009_ExportFramework3.cs index 093398f968..b3b39a74de 100644 --- a/src/Libraries/SmartStore.Data/Migrations/201511121139009_ExportFramework3.cs +++ b/src/Libraries/SmartStore.Data/Migrations/201511121139009_ExportFramework3.cs @@ -39,7 +39,7 @@ public void Seed(SmartObjectContext context) { Name = "Admin area. Manage Url Records", SystemName = "ManageUrlRecords", - Category = "Standard" + Category = "Configuration" }, new string[] { SystemCustomerRoleNames.Administrators }); diff --git a/src/Libraries/SmartStore.Services/Security/StandardPermissionProvider.cs b/src/Libraries/SmartStore.Services/Security/StandardPermissionProvider.cs index 4f37e81bb0..886196b240 100644 --- a/src/Libraries/SmartStore.Services/Security/StandardPermissionProvider.cs +++ b/src/Libraries/SmartStore.Services/Security/StandardPermissionProvider.cs @@ -50,7 +50,7 @@ public partial class StandardPermissionProvider : IPermissionProvider public static readonly PermissionRecord UploadPictures = new PermissionRecord { Name = "Admin area. Upload Pictures", SystemName = "UploadPictures", Category = "Configuration" }; public static readonly PermissionRecord ManageScheduleTasks = new PermissionRecord { Name = "Admin area. Manage Schedule Tasks", SystemName = "ManageScheduleTasks", Category = "Configuration" }; public static readonly PermissionRecord ManageExports = new PermissionRecord { Name = "Admin area. Manage Exports", SystemName = "ManageExports", Category = "Configuration" }; - public static readonly PermissionRecord ManageUrlRecords = new PermissionRecord { Name = "Admin area. Manage Url Records", SystemName = "ManageUrlRecords", Category = "Standard" }; + public static readonly PermissionRecord ManageUrlRecords = new PermissionRecord { Name = "Admin area. Manage Url Records", SystemName = "ManageUrlRecords", Category = "Configuration" }; //public store permissions public static readonly PermissionRecord DisplayPrices = new PermissionRecord { Name = "Public store. Display Prices", SystemName = "DisplayPrices", Category = "PublicStore" }; From 97eecfbaf4d9b15f15ae217600da356168e20163 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Tue, 17 Nov 2015 14:21:28 +0100 Subject: [PATCH 037/626] Export framework should not create empty files --- src/Libraries/SmartStore.Services/DataExchange/DataExporter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Libraries/SmartStore.Services/DataExchange/DataExporter.cs b/src/Libraries/SmartStore.Services/DataExchange/DataExporter.cs index 1fb126c0de..eb1a0d2306 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/DataExporter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/DataExporter.cs @@ -383,7 +383,7 @@ private bool CallProvider(DataExporterContext ctx, string streamId, string metho ctx.Request.Provider.Value.OnExecuted(ctx.ExecuteContext); } - if (ctx.IsFileBasedExport && path.HasValue()) + if (ctx.IsFileBasedExport && path.HasValue() && ctx.ExecuteContext.DataStream.Length > 0) { if (!ctx.ExecuteContext.DataStream.CanSeek) ctx.Log.Warning("Data stream seems to be closed!"); From 96156cf5001dc4cfb19df3fd7b1fc0fdb2a1d088 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Tue, 17 Nov 2015 15:31:50 +0100 Subject: [PATCH 038/626] Perf: Statically cache types of payment method filters and shipping method filters --- .../Payments/PaymentService.cs | 27 +++++++++++++++---- .../Shipping/ShippingService.cs | 25 ++++++++++++++--- 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/src/Libraries/SmartStore.Services/Payments/PaymentService.cs b/src/Libraries/SmartStore.Services/Payments/PaymentService.cs index 6a5587bc72..9280f99bb0 100644 --- a/src/Libraries/SmartStore.Services/Payments/PaymentService.cs +++ b/src/Libraries/SmartStore.Services/Payments/PaymentService.cs @@ -25,10 +25,13 @@ public partial class PaymentService : IPaymentService #region Constants private const string PAYMENTMETHOD_ALL_KEY = "SmartStore.paymentmethod.all"; - + #endregion - #region Fields + #region Fields + + private readonly static object _lock = new object(); + private static IList _paymentMethodFilterTypes = null; private readonly IRepository _paymentMethodRepository; private readonly PaymentSettings _paymentSettings; @@ -722,11 +725,25 @@ public virtual string GetMaskedCreditCardNumber(string creditCardNumber) public virtual IList GetAllPaymentMethodFilters() { - return _typeFinder.FindClassesOfType(ignoreInactivePlugins: true) + if (_paymentMethodFilterTypes == null) + { + lock (_lock) + { + if (_paymentMethodFilterTypes == null) + { + _paymentMethodFilterTypes = _typeFinder.FindClassesOfType(ignoreInactivePlugins: true) + .ToList(); + } + } + } + + var paymentMethodFilters = _paymentMethodFilterTypes .Select(x => EngineContext.Current.ContainerManager.ResolveUnregistered(x) as IPaymentMethodFilter) .ToList(); + + return paymentMethodFilters; } - #endregion - } + #endregion + } } diff --git a/src/Libraries/SmartStore.Services/Shipping/ShippingService.cs b/src/Libraries/SmartStore.Services/Shipping/ShippingService.cs index 78d21c628b..6b35961b79 100644 --- a/src/Libraries/SmartStore.Services/Shipping/ShippingService.cs +++ b/src/Libraries/SmartStore.Services/Shipping/ShippingService.cs @@ -22,9 +22,12 @@ namespace SmartStore.Services.Shipping { public partial class ShippingService : IShippingService { - #region Fields + #region Fields - private readonly IRepository _shippingMethodRepository; + private readonly static object _lock = new object(); + private static IList _shippingMethodFilterTypes = null; + + private readonly IRepository _shippingMethodRepository; private readonly ICacheManager _cacheManager; private readonly ILogger _logger; private readonly IProductAttributeParser _productAttributeParser; @@ -461,10 +464,24 @@ public virtual GetShippingOptionResponse GetShippingOptions(IList GetAllShippingMethodFilters() { - return _typeFinder.FindClassesOfType(ignoreInactivePlugins: true) + if (_shippingMethodFilterTypes == null) + { + lock (_lock) + { + if (_shippingMethodFilterTypes == null) + { + _shippingMethodFilterTypes = _typeFinder.FindClassesOfType(ignoreInactivePlugins: true) + .ToList(); + } + } + } + + var shippingMethodFilters = _shippingMethodFilterTypes .Select(x => EngineContext.Current.ContainerManager.ResolveUnregistered(x) as IShippingMethodFilter) .ToList(); - } + + return shippingMethodFilters; + } #endregion From 96a50f743bea96947c3970300284e03fba81c862 Mon Sep 17 00:00:00 2001 From: Murat Cakir Date: Tue, 17 Nov 2015 18:40:38 +0100 Subject: [PATCH 039/626] Export framework: minor refactoring --- .../SmartStore.Core/Data/IDbContext.cs | 20 ++++++--- .../Data/IDbContextExtensions.cs | 5 +++ .../SmartStore.Data/ObjectContextBase.cs | 41 +++++-------------- .../DataExchange/DataExporter.cs | 24 +++++------ .../DataExchange/DynamicEntityHelper.cs | 23 ++++++++--- 5 files changed, 59 insertions(+), 54 deletions(-) diff --git a/src/Libraries/SmartStore.Core/Data/IDbContext.cs b/src/Libraries/SmartStore.Core/Data/IDbContext.cs index cec8a1a2ce..cb276a03ac 100644 --- a/src/Libraries/SmartStore.Core/Data/IDbContext.cs +++ b/src/Libraries/SmartStore.Core/Data/IDbContext.cs @@ -87,12 +87,20 @@ IList ExecuteStoredProcedureList(string commandText, params ob /// true when the entity is attched already, false otherwise bool IsAttached(TEntity entity) where TEntity : BaseEntity; - /// - /// Detaches an entity from the current object context if it's attached - /// - /// Type of entity - /// The entity instance to detach - void DetachEntity(TEntity entity) where TEntity : BaseEntity; + /// + /// Attaches an entity to the context or returns an already attached entity (if it was already attached) + /// + /// Type of entity + /// Entity + /// Attached entity + TEntity Attach(TEntity entity) where TEntity : BaseEntity; + + /// + /// Detaches an entity from the current object context if it's attached + /// + /// Type of entity + /// The entity instance to detach + void DetachEntity(TEntity entity) where TEntity : BaseEntity; /// /// Detaches all entities of type TEntity from the current object context diff --git a/src/Libraries/SmartStore.Core/Data/IDbContextExtensions.cs b/src/Libraries/SmartStore.Core/Data/IDbContextExtensions.cs index 0889cd6684..c4c1c82196 100644 --- a/src/Libraries/SmartStore.Core/Data/IDbContextExtensions.cs +++ b/src/Libraries/SmartStore.Core/Data/IDbContextExtensions.cs @@ -167,5 +167,10 @@ public static void LoadReference( } } + public static void AttachRange(this IDbContext ctx, IEnumerable entities) where TEntity : BaseEntity + { + entities.Each(x => ctx.Attach(x)); + } + } } diff --git a/src/Libraries/SmartStore.Data/ObjectContextBase.cs b/src/Libraries/SmartStore.Data/ObjectContextBase.cs index 278d88d984..5db3d6b0ef 100644 --- a/src/Libraries/SmartStore.Data/ObjectContextBase.cs +++ b/src/Libraries/SmartStore.Data/ObjectContextBase.cs @@ -191,7 +191,7 @@ private IEnumerable ToParameters(params object[] parameters) { for (int i = 0; i < result.Count; i++) { - result[i] = AttachEntity(result[i]); + result[i] = Attach(result[i]); } } } @@ -224,7 +224,7 @@ private IEnumerable ToParameters(params object[] parameters) { for (int i = 0; i < result.Count; i++) { - result[i] = AttachEntity(result[i]); + result[i] = Attach(result[i]); } } // close up the reader, we're done saving results @@ -336,13 +336,14 @@ public IDictionary GetModifiedProperties(BaseEntity entity) // be aware of the entity state. you cannot get modified properties for detached entities. if (entry.State != System.Data.Entity.EntityState.Detached) { - var modifiedPropertyNames = from p in entry.CurrentValues.PropertyNames - where entry.Property(p).IsModified - select p; + var modifiedProperties = from p in entry.CurrentValues.PropertyNames + let prop = entry.Property(p) + where prop.IsModified + select prop; - foreach (var name in modifiedPropertyNames) + foreach (var prop in modifiedProperties) { - props.Add(name, entry.Property(name).OriginalValue); + props.Add(prop.Name, prop.OriginalValue); } } @@ -495,8 +496,9 @@ protected internal bool IsSqlServer2012OrHigher() return s_isSqlServer2012OrHigher.Value; } - private TEntity Attach(DbSet dbSet, TEntity entity) where TEntity : BaseEntity - { + public TEntity Attach(TEntity entity) where TEntity : BaseEntity + { + var dbSet = Set(); var alreadyAttached = dbSet.Local.FirstOrDefault(x => x.Id == entity.Id); if (alreadyAttached == null) @@ -508,27 +510,6 @@ private TEntity Attach(DbSet dbSet, TEntity entity) where TEnt return alreadyAttached; } - /// - /// Attach an entity to the context or return an already attached entity (if it was already attached) - /// - /// TEntity - /// Entity - /// Attached entity - public TEntity AttachEntity(TEntity entity) where TEntity : BaseEntity - { - // little hack here until Entity Framework really supports stored procedures - // otherwise, navigation properties of loaded entities are not loaded until an entity is attached to the context - - return Attach(Set(), entity); - } - - public void AttachEntities(IEnumerable entities) where TEntity : BaseEntity - { - var dbSet = Set(); - - entities.Each(entity => Attach(dbSet, entity)); - } - public bool IsAttached(TEntity entity) where TEntity : BaseEntity { if (entity != null) diff --git a/src/Libraries/SmartStore.Services/DataExchange/DataExporter.cs b/src/Libraries/SmartStore.Services/DataExchange/DataExporter.cs index eb1a0d2306..5f7650cf10 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/DataExporter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/DataExporter.cs @@ -211,11 +211,8 @@ private void DetachAllEntitiesAndClear(DataExporterContext ctx) try { // now again attach what is globally required - var dataContextBase = _dbContext as ObjectContextBase; - - dataContextBase.AttachEntity(ctx.Request.Profile); - - dataContextBase.AttachEntities(ctx.Stores.Values); + _dbContext.Attach(ctx.Request.Profile); + _dbContext.AttachRange(ctx.Stores.Values); } catch (Exception exception) { @@ -439,24 +436,27 @@ private void Deploy(DataExporterContext ctx) try { + IFilePublisher publisher = null; + if (deployment.DeploymentType == ExportDeploymentType.Email) { - var publisher = new EmailFilePublisher(_emailAccountService.Value, _queuedEmailService.Value); - publisher.Publish(context, deployment); + publisher = new EmailFilePublisher(_emailAccountService.Value, _queuedEmailService.Value); } else if (deployment.DeploymentType == ExportDeploymentType.FileSystem) { - var publisher = new FileSystemFilePublisher(); - publisher.Publish(context, deployment); + publisher = new FileSystemFilePublisher(); } else if (deployment.DeploymentType == ExportDeploymentType.Ftp) { - var publisher = new FtpFilePublisher(); - publisher.Publish(context, deployment); + publisher = new FtpFilePublisher(); } else if (deployment.DeploymentType == ExportDeploymentType.Http) { - var publisher = new HttpFilePublisher(); + publisher = new HttpFilePublisher(); + } + + if (publisher != null) + { publisher.Publish(context, deployment); } } diff --git a/src/Libraries/SmartStore.Services/DataExchange/DynamicEntityHelper.cs b/src/Libraries/SmartStore.Services/DataExchange/DynamicEntityHelper.cs index f88aa7cda1..9e4940d4e7 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/DynamicEntityHelper.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/DynamicEntityHelper.cs @@ -540,7 +540,9 @@ private dynamic ToDynamic(DataExporterContext ctx, Product product) return result; } - private dynamic ToDynamic(DataExporterContext ctx, Product product, + private dynamic ToDynamic( + DataExporterContext ctx, + Product product, ICollection combinations, ProductVariantAttributeCombination combination) { @@ -655,7 +657,7 @@ private dynamic ToDynamic(DataExporterContext ctx, Product product, .Select(x => ToDynamic(ctx, x)) .ToList(); - dynObject.ProductAttributeCombinations = combinations + dynObject.ProductAttributeCombinations = (combinations ?? Enumerable.Empty()) .Select(x => { dynamic dyn = ToDynamic(ctx, x); @@ -948,13 +950,20 @@ private List Convert(DataExporterContext ctx, Product product) { var result = new List(); - var combinations = ctx.ProductExportContext.AttributeCombinations.Load(product.Id); + var hasAttributeCombinations = false; - if (!ctx.IsPreview && ctx.Projection.AttributeCombinationAsProduct && combinations.Where(x => x.IsActive).Count() > 0) + if (!ctx.IsPreview && ctx.Projection.AttributeCombinationAsProduct) + { + hasAttributeCombinations = _dbContext.QueryForCollection(product, (Product p) => p.ProductVariantAttributeCombinations).Where(c => c.IsActive).Any(); + } + + if (hasAttributeCombinations) { var productType = typeof(Product); var productValues = new Dictionary(); + // TODO: work with Entry().CurrentValues instead of Reflection. + // First attach the object, determine all values and detach again. var properties = FastProperty.GetProperties(product.GetUnproxiedType()) .Values .Where(x => x.Property.CanRead && x.Property.CanWrite); @@ -965,7 +974,9 @@ private List Convert(DataExporterContext ctx, Product product) productValues.Add(property.Name, property.GetValue(product)); } - foreach (var combination in combinations.Where(x => x.IsActive)) + var combinations = ctx.ProductExportContext.AttributeCombinations.Load(product.Id); + + foreach (var combination in combinations) { var productClone = new Product(); @@ -980,7 +991,7 @@ private List Convert(DataExporterContext ctx, Product product) } else { - var dynObject = ToDynamic(ctx, product, combinations, null); + var dynObject = ToDynamic(ctx, product, null, null); result.Add(dynObject); } From fd08f0367ae431ed67e4776ec930a341450275a0 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Wed, 18 Nov 2015 11:25:41 +0100 Subject: [PATCH 040/626] Changed folder for export profiles --- .gitignore | 1 + .../SmartStore.Services/DataExchange/ExportExtensions.cs | 8 ++++++-- .../DataExchange/Internal/DataExporterContext.cs | 3 +-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 3b997b1c64..460b0b95df 100644 --- a/.gitignore +++ b/.gitignore @@ -200,6 +200,7 @@ Kopie von* /build /src/Presentation/SmartStore.Web/Plugins /src/Presentation/SmartStore.Web/App_Data/_temp/ +/src/Presentation/SmartStore.Web/App_Data/ExportProfiles/ /src/Presentation/SmartStore.Web/App_Data/Settings.txt /src/Presentation/SmartStore.Web/App_Data/InstalledPlugins.txt /src/Presentation/SmartStore.Web/App_Data/Licenses.lic diff --git a/src/Libraries/SmartStore.Services/DataExchange/ExportExtensions.cs b/src/Libraries/SmartStore.Services/DataExchange/ExportExtensions.cs index cf86f0d411..f46fb9094a 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/ExportExtensions.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/ExportExtensions.cs @@ -42,9 +42,13 @@ public static string GetName(this Provider provider, ILocalizat /// /// Export profile /// Folder path - public static string GetExportFolder(this ExportProfile profile, bool content = false) + public static string GetExportFolder(this ExportProfile profile, bool content = false, bool create = false) { - var path = Path.Combine(FileSystemHelper.TempDir(), @"Profile\Export\{0}{1}".FormatInvariant(profile.FolderName, content ? @"\Content" : "")); + var path = CommonHelper.MapPath(string.Concat("~/App_Data/ExportProfiles/", profile.FolderName, content ? "/Content" : "")); + + if (create && !System.IO.Directory.Exists(path)) + System.IO.Directory.CreateDirectory(path); + return path; } diff --git a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporterContext.cs b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporterContext.cs index 0d44c9843e..031406df3a 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporterContext.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporterContext.cs @@ -10,7 +10,6 @@ using SmartStore.Core.Domain.Localization; using SmartStore.Core.Domain.Stores; using SmartStore.Core.Logging; -using SmartStore.Utilities; namespace SmartStore.Services.DataExchange.Internal { @@ -27,7 +26,7 @@ public DataExporterContext( Projection = XmlHelper.Deserialize(request.Profile.Projection); IsPreview = isPreview; - FolderContent = FileSystemHelper.TempDir(@"Profile\Export\{0}\Content".FormatInvariant(request.Profile.FolderName)); + FolderContent = request.Profile.GetExportFolder(true, true); FolderRoot = System.IO.Directory.GetParent(FolderContent).FullName; Categories = new Dictionary(); From 86b8d4485487debfd34c088fb581a6afbec9da3c Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Wed, 18 Nov 2015 18:04:25 +0100 Subject: [PATCH 041/626] Added column with export file number in export profile list --- .../201511121139009_ExportFramework3.cs | 6 +- .../DataExchange/DataExporter.cs | 22 ++--- .../DataExchange/ExportExtensions.cs | 36 +++++++- .../Internal/DataExporterContext.cs | 15 ---- .../Controllers/ExportController.cs | 83 +++++++++++++++++-- .../Models/DataExchange/ExportProfileModel.cs | 20 +++++ .../Administration/SmartStore.Admin.csproj | 2 + .../Administration/Views/Export/Edit.cshtml | 2 +- .../Administration/Views/Export/List.cshtml | 53 ++++++++++-- .../Views/Export/ProfileFileCount.cshtml | 13 +++ .../Views/Export/ProfileFileDetails.cshtml | 23 +++++ .../Views/Export/_Tab.Deployment.cshtml | 1 - 12 files changed, 235 insertions(+), 41 deletions(-) create mode 100644 src/Presentation/SmartStore.Web/Administration/Views/Export/ProfileFileCount.cshtml create mode 100644 src/Presentation/SmartStore.Web/Administration/Views/Export/ProfileFileDetails.cshtml diff --git a/src/Libraries/SmartStore.Data/Migrations/201511121139009_ExportFramework3.cs b/src/Libraries/SmartStore.Data/Migrations/201511121139009_ExportFramework3.cs index b3b39a74de..acf47b44eb 100644 --- a/src/Libraries/SmartStore.Data/Migrations/201511121139009_ExportFramework3.cs +++ b/src/Libraries/SmartStore.Data/Migrations/201511121139009_ExportFramework3.cs @@ -197,7 +197,11 @@ public void MigrateLocaleResources(LocaleResourcesBuilder builder) builder.AddOrUpdate("Admin.DataExchange.Export.MissingSystemProfile", "The system export profile {0} was not found.", "Das System-Exportprofil {0} wurde nicht gefunden."); - } + + builder.AddOrUpdate("Admin.DataExchange.Export.ExportFiles", + "Export files", + "Exportdateien"); + } } diff --git a/src/Libraries/SmartStore.Services/DataExchange/DataExporter.cs b/src/Libraries/SmartStore.Services/DataExchange/DataExporter.cs index 5f7650cf10..25a0651cbd 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/DataExporter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/DataExporter.cs @@ -415,22 +415,21 @@ private bool CallProvider(DataExporterContext ctx, string streamId, string metho return (ctx.ExecuteContext.Abort != ExportAbortion.Hard); } - private void Deploy(DataExporterContext ctx) + private void Deploy(DataExporterContext ctx, string zipPath) { - var containerManager = EngineContext.Current.ContainerManager; var allFiles = System.IO.Directory.GetFiles(ctx.FolderContent, "*.*", SearchOption.AllDirectories); var context = new ExportDeploymentContext { Log = ctx.Log, FolderContent = ctx.FolderContent, - ZipPath = ctx.ZipPath + ZipPath = zipPath }; foreach (var deployment in ctx.Request.Profile.Deployments.OrderBy(x => x.DeploymentTypeId).Where(x => x.Enabled)) { if (deployment.CreateZip) - context.DeploymentFiles = new string[] { ctx.ZipPath }; + context.DeploymentFiles = new string[] { zipPath }; else context.DeploymentFiles = allFiles; @@ -977,11 +976,14 @@ private void ExportCoreOuter(DataExporterContext ctx) if (ctx.Request.Profile == null || !ctx.Request.Profile.Enabled) return; - FileSystemHelper.Delete(ctx.LogPath); + var logPath = ctx.Request.Profile.GetExportLogPath(); + var zipPath = ctx.Request.Profile.GetExportZipPath(); + + FileSystemHelper.Delete(logPath); + FileSystemHelper.Delete(zipPath); FileSystemHelper.ClearDirectory(ctx.FolderContent, false); - FileSystemHelper.Delete(ctx.ZipPath); - using (var logger = new TraceLogger(ctx.LogPath)) + using (var logger = new TraceLogger(logPath)) { try { @@ -1053,14 +1055,14 @@ private void ExportCoreOuter(DataExporterContext ctx) { if (ctx.Request.Profile.CreateZipArchive || ctx.Request.Profile.Deployments.Any(x => x.Enabled && x.CreateZip)) { - ZipFile.CreateFromDirectory(ctx.FolderContent, ctx.ZipPath, CompressionLevel.Fastest, true); + ZipFile.CreateFromDirectory(ctx.FolderContent, zipPath, CompressionLevel.Fastest, true); } if (ctx.Request.Profile.Deployments.Any(x => x.Enabled)) { SetProgress(ctx, T("Common.Deployment")); - Deploy(ctx); + Deploy(ctx, zipPath); } } @@ -1127,7 +1129,7 @@ private void ExportCoreOuter(DataExporterContext ctx) // post process order entities if (ctx.EntityIdsLoaded.Count > 0 && ctx.Request.Provider.Value.EntityType == ExportEntityType.Order && ctx.Projection.OrderStatusChange != ExportOrderStatusChange.None) { - using (var logger = new TraceLogger(ctx.LogPath)) + using (var logger = new TraceLogger(logPath)) { try { diff --git a/src/Libraries/SmartStore.Services/DataExchange/ExportExtensions.cs b/src/Libraries/SmartStore.Services/DataExchange/ExportExtensions.cs index f46fb9094a..4de3aadd7c 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/ExportExtensions.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/ExportExtensions.cs @@ -1,6 +1,8 @@ using System; +using System.Collections.Generic; using System.Globalization; using System.IO; +using System.Linq; using System.Text; using SmartStore.Core.Domain; using SmartStore.Core.Domain.Stores; @@ -57,12 +59,40 @@ public static string GetExportFolder(this ExportProfile profile, bool content = /// /// Export profile /// Log file path - public static string GetExportLogFilePath(this ExportProfile profile) + public static string GetExportLogPath(this ExportProfile profile) { - var path = Path.Combine(profile.GetExportFolder(), "log.txt"); - return path; + return Path.Combine(profile.GetExportFolder(), "log.txt"); + } + + /// + /// Gets the ZIP path for a profile + /// + /// Export profile + /// ZIP file path + public static string GetExportZipPath(this ExportProfile profile) + { + return Path.Combine(profile.GetExportFolder(), profile.FolderName + ".zip"); } + /// + /// Gets existing export files for an export profile + /// + /// Export profile + /// List of file names + public static List GetExportFiles(this ExportProfile profile) + { + var exportFolder = profile.GetExportFolder(true); + + if (System.IO.Directory.Exists(exportFolder)) + { + return System.IO.Directory.EnumerateFiles(exportFolder, "*", SearchOption.TopDirectoryOnly) + .OrderBy(x => x) + .ToList(); + } + + return new List(); + } + /// /// Resolves the file name pattern for an export profile /// diff --git a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporterContext.cs b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporterContext.cs index 031406df3a..0b09514a17 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporterContext.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporterContext.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using System.IO; using System.Linq; using System.Threading; using SmartStore.Core; @@ -27,7 +26,6 @@ public DataExporterContext( IsPreview = isPreview; FolderContent = request.Profile.GetExportFolder(true, true); - FolderRoot = System.IO.Directory.GetParent(FolderContent).FullName; Categories = new Dictionary(); CategoryPathes = new Dictionary(); @@ -87,20 +85,7 @@ public bool Supports(ExportFeatures feature) public TraceLogger Log { get; set; } public Store Store { get; set; } - public string FolderRoot { get; private set; } public string FolderContent { get; private set; } - public string ZipName - { - get { return Request.Profile.FolderName + ".zip"; } - } - public string ZipPath - { - get { return Path.Combine(FolderRoot, ZipName); } - } - public string LogPath - { - get { return Path.Combine(FolderRoot, "log.txt"); } - } public bool IsFileBasedExport { diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs index 5fafb8d0df..aba647e6cf 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs @@ -16,12 +16,12 @@ using SmartStore.Core.Domain.Payments; using SmartStore.Core.Domain.Shipping; using SmartStore.Core.Domain.Stores; +using SmartStore.Core.IO; using SmartStore.Core.Plugins; using SmartStore.Services; using SmartStore.Services.Catalog; using SmartStore.Services.Customers; using SmartStore.Services.DataExchange; -using SmartStore.Services.DataExchange.Internal; using SmartStore.Services.Directory; using SmartStore.Services.Helpers; using SmartStore.Services.Localization; @@ -106,6 +106,20 @@ private string GetThumbnailUrl(Provider provider) return url; } + private ExportProfileDetailsModel PrepareProfileDetailsModel(ExportProfile profile) + { + var zipPath = profile.GetExportZipPath(); + + var model = new ExportProfileDetailsModel + { + Id = profile.Id, + ZipPath = (System.IO.File.Exists(zipPath) ? zipPath : null), + ExportFiles = profile.GetExportFiles() + }; + + return model; + } + private void PrepareProfileModel(ExportProfileModel model, ExportProfile profile, Provider provider) { model.Id = profile.Id; @@ -120,13 +134,15 @@ private void PrepareProfileModel(ExportProfileModel model, ExportProfile profile model.ScheduleTaskName = profile.ScheduleTask.Name.NaIfEmpty(); model.IsTaskRunning = profile.ScheduleTask.IsRunning; model.IsTaskEnabled = profile.ScheduleTask.Enabled; - model.LogFileExists = System.IO.File.Exists(profile.GetExportLogFilePath()); + model.LogFileExists = System.IO.File.Exists(profile.GetExportLogPath()); model.HasActiveProvider = (provider != null); model.FileNamePatternDescriptions = T("Admin.DataExchange.Export.FileNamePatternDescriptions").Text.SplitSafe(";"); model.Provider = new ExportProfileModel.ProviderModel(); model.Provider.ThumbnailUrl = GetThumbnailUrl(provider); + model.Details = PrepareProfileDetailsModel(profile); + if (provider != null) { var descriptor = provider.Metadata.PluginDescriptor; @@ -145,7 +161,7 @@ private void PrepareProfileModel(ExportProfileModel model, ExportProfile profile model.Provider.EntityTypeName = provider.Value.EntityType.GetLocalizedEnum(_services.Localization, _services.WorkContext); model.Provider.FileExtension = provider.Value.FileExtension; } - } + } private void PrepareProfileModelForEdit(ExportProfileModel model, ExportProfile profile, Provider provider) { @@ -478,6 +494,41 @@ public ActionResult List() return View(model); } + public ActionResult ProfileListDetails(int profileId) + { + if (_services.Permissions.Authorize(StandardPermissionProvider.ManageExports)) + { + var profile = _exportService.GetExportProfileById(profileId); + if (profile != null) + { + var model = PrepareProfileDetailsModel(profile); + + return Json(new + { + exportFileCount = this.RenderPartialViewToString("ProfileFileCount", model) + }, JsonRequestBehavior.AllowGet); + } + } + + return new EmptyResult(); + } + + public ActionResult ProfileFileDetails(int profileId) + { + if (_services.Permissions.Authorize(StandardPermissionProvider.ManageExports)) + { + var profile = _exportService.GetExportProfileById(profileId); + if (profile != null) + { + var model = PrepareProfileDetailsModel(profile); + + return PartialView(model); + } + } + + return new EmptyResult(); + } + public ActionResult Create() { if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageExports)) @@ -742,7 +793,7 @@ public ActionResult Preview(int id) GridPageSize = DataExporter.PageSize, EntityType = provider.Value.EntityType, TotalRecords = totalRecords, - LogFileExists = System.IO.File.Exists(profile.GetExportLogFilePath()), + LogFileExists = System.IO.File.Exists(profile.GetExportLogPath()), UsernamesEnabled = _customerSettings.Value.UsernamesEnabled }; @@ -979,7 +1030,7 @@ public ActionResult DownloadLogFile(int id) if (profile == null) return RedirectToAction("List"); - var path = profile.GetExportLogFilePath(); + var path = profile.GetExportLogPath(); var stream = new FileStream(path, FileMode.Open); var result = new FileStreamResult(stream, "text/plain; charset=utf-8"); @@ -988,6 +1039,28 @@ public ActionResult DownloadLogFile(int id) return result; } + public ActionResult DownloadExportFile(int id, string name) + { + if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageExports)) + return AccessDeniedView(); + + var profile = _exportService.GetExportProfileById(id); + if (profile == null) + return RedirectToAction("List"); + + var path = Path.Combine(profile.GetExportFolder(true), name); + + if (!System.IO.File.Exists(path)) + path = Path.Combine(profile.GetExportFolder(false), name); + + var stream = new FileStream(path, FileMode.Open); + + var result = new FileStreamResult(stream, MimeTypes.MapNameToMimeType(path)); + result.FileDownloadName = Path.GetFileName(path); + + return result; + } + public ActionResult ResolveFileNamePatternExample(int id, string pattern) { var profile = _exportService.GetExportProfileById(id); diff --git a/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ExportProfileModel.cs b/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ExportProfileModel.cs index 7ea59f0921..b41f8fc1f5 100644 --- a/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ExportProfileModel.cs +++ b/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ExportProfileModel.cs @@ -95,6 +95,8 @@ public partial class ExportProfileModel : EntityModelBase public ScheduleTaskModel TaskModel { get; set; } + public ExportProfileDetailsModel Details { get; set; } + public class ProviderModel { public string ConfigPartialViewName { get; set; } @@ -152,4 +154,22 @@ public class ProviderSelectItem public string Description { get; set; } } } + + + public partial class ExportProfileDetailsModel : EntityModelBase + { + [SmartResourceDisplayName("Admin.DataExchange.Export.ExportFiles")] + public List ExportFiles { get; set; } + + public string ZipPath { get; set; } + + [SmartResourceDisplayName("Admin.DataExchange.Export.ExportFiles")] + public int ExportFileCount + { + get + { + return (ExportFiles.Count + (ZipPath.HasValue() ? 1 : 0)); + } + } + } } \ No newline at end of file diff --git a/src/Presentation/SmartStore.Web/Administration/SmartStore.Admin.csproj b/src/Presentation/SmartStore.Web/Administration/SmartStore.Admin.csproj index 5bc8e616ad..189b2f717d 100644 --- a/src/Presentation/SmartStore.Web/Administration/SmartStore.Admin.csproj +++ b/src/Presentation/SmartStore.Web/Administration/SmartStore.Admin.csproj @@ -535,6 +535,8 @@ + + diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Export/Edit.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Export/Edit.cshtml index ecf22fd744..17a71d5ebc 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Export/Edit.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Export/Edit.cshtml @@ -25,7 +25,7 @@ } @if (Model.LogFileExists) { - +  @T("Admin.Configuration.ActivityLog") } diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Export/List.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Export/List.cshtml index 6448df05a3..c1e1a0beb3 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Export/List.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Export/List.cshtml @@ -27,11 +27,12 @@ @T("Common.Image") @T("Admin.DataExchange.Export.Name") + @T("Admin.DataExchange.Export.IsSystemProfile") @T("Common.Provider") @T("Common.Enabled") @T("Admin.DataExchange.Export.EntityType") @T("Admin.DataExchange.Export.FileExtension") - @T("Admin.DataExchange.Export.IsSystemProfile") + @T("Admin.DataExchange.Export.ExportFiles") @T("Admin.System.ScheduleTasks.LastStart") @T("Admin.System.ScheduleTasks.NextRun") @T("Admin.Common.Actions") @@ -40,7 +41,7 @@ @foreach (var profile in Model) { - + @profile.Provider.FriendlyName @@ -51,6 +52,9 @@
@profile.SystemName
} + + @Html.SymbolForBool(profile.IsSystemProfile) + @if (profile.Provider.ConfigurationUrl.HasValue()) { @@ -71,8 +75,8 @@ @Html.IconForFileExtension(profile.Provider.FileExtension, true) - - @Html.SymbolForBool(profile.IsSystemProfile) + + @Html.Partial("ProfileFileCount", profile.Details)
@@ -127,6 +131,17 @@ else
+ + -} - - - - +} \ No newline at end of file diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Product/List.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Product/List.cshtml index 129406b9a5..9d9bacaa8a 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Product/List.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Product/List.cshtml @@ -37,13 +37,13 @@ @@ -217,7 +217,7 @@ \ No newline at end of file From 5a05d01dea5c2e8cc779617a573874168825b41d Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Fri, 27 Nov 2015 14:17:19 +0100 Subject: [PATCH 060/626] Added manufacturer CSV export --- .../Controllers/ManufacturerController.cs | 19 +++--- .../Models/Catalog/ManufacturerListModel.cs | 5 +- .../Views/Manufacturer/List.cshtml | 61 +++++++++++++++++-- 3 files changed, 66 insertions(+), 19 deletions(-) diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/ManufacturerController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/ManufacturerController.cs index 6d40857243..1382fe86c0 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/ManufacturerController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/ManufacturerController.cs @@ -241,14 +241,12 @@ public ActionResult List() if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) return AccessDeniedView(); - var model = new ManufacturerListModel(); - var manufacturers = _manufacturerService.GetAllManufacturers(null, 0, _adminAreaSettings.GridPageSize, true); - model.Manufacturers = new GridModel - { - Data = manufacturers.Select(x => x.ToModel()), - Total = manufacturers.TotalCount - }; - return View(model); + var model = new ManufacturerListModel + { + GridPageSize = _adminAreaSettings.GridPageSize + }; + + return View(model); } [HttpPost, GridAction(EnableCustomBinding = true)] @@ -257,13 +255,14 @@ public ActionResult List(GridCommand command, ManufacturerListModel model) if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) return AccessDeniedView(); - var manufacturers = _manufacturerService.GetAllManufacturers(model.SearchManufacturerName, - command.Page - 1, command.PageSize, true); + var manufacturers = _manufacturerService.GetAllManufacturers(model.SearchManufacturerName, command.Page - 1, command.PageSize, true); + var gridModel = new GridModel { Data = manufacturers.Select(x => x.ToModel()), Total = manufacturers.TotalCount }; + return new JsonResult { Data = gridModel diff --git a/src/Presentation/SmartStore.Web/Administration/Models/Catalog/ManufacturerListModel.cs b/src/Presentation/SmartStore.Web/Administration/Models/Catalog/ManufacturerListModel.cs index 9fedd4f0bd..f683ac54c0 100644 --- a/src/Presentation/SmartStore.Web/Administration/Models/Catalog/ManufacturerListModel.cs +++ b/src/Presentation/SmartStore.Web/Administration/Models/Catalog/ManufacturerListModel.cs @@ -1,16 +1,15 @@ using System.Web.Mvc; using SmartStore.Web.Framework; using SmartStore.Web.Framework.Mvc; -using Telerik.Web.Mvc; namespace SmartStore.Admin.Models.Catalog { - public class ManufacturerListModel : ModelBase + public class ManufacturerListModel : ModelBase { [SmartResourceDisplayName("Admin.Catalog.Manufacturers.List.SearchManufacturerName")] [AllowHtml] public string SearchManufacturerName { get; set; } - public GridModel Manufacturers { get; set; } + public int GridPageSize { get; set; } } } \ No newline at end of file diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Manufacturer/List.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Manufacturer/List.cshtml index 4d867bfcad..c5f8fccc99 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Manufacturer/List.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Manufacturer/List.cshtml @@ -1,8 +1,6 @@ @model ManufacturerListModel @using Telerik.Web.Mvc.UI -@{ - var gridPageSize = EngineContext.Current.Resolve().GridPageSize; - +@{ ViewBag.Title = T("Admin.Catalog.Manufacturers").Text; }
@@ -45,12 +43,19 @@
- @(Html.Telerik().Grid(Model.Manufacturers.Data) + @(Html.Telerik().Grid() .Name("manufacturers-grid") .ClientEvents(events => events - .OnDataBinding("onDataBinding")) + .OnDataBinding("onDataBinding") + .OnDataBound("onDataBound")) .Columns(columns => { + columns.Bound(x => x.Id) + .ClientTemplate("") + .Title("") + .Width(50) + .HtmlAttributes(new { style = "text-align:center" }) + .HeaderHtmlAttributes(new { style = "text-align:center" }); columns.Bound(x => x.Name) .Template(x => Html.ActionLink(x.Name, "Edit", new { id = x.Id })) .ClientTemplate("\"><#= Name #>"); @@ -68,7 +73,7 @@ .ClientTemplate(@Html.SymbolForBool("LimitedToStores")) .Centered(); }) - .Pageable(settings => settings.Total(Model.Manufacturers.Total).PageSize(gridPageSize).Position(GridPagerPosition.Both)) + .Pageable(settings => settings.PageSize(Model.GridPageSize).Position(GridPagerPosition.Both)) .DataBinding(dataBinding => dataBinding.Ajax().Select("List", "Manufacturer")) .PreserveGridState() .EnableCustomBinding(true)) @@ -77,6 +82,9 @@
\ No newline at end of file From fcc2608a7f946272da638d8c2331eb114d2f63e0 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Mon, 30 Nov 2015 10:57:39 +0100 Subject: [PATCH 061/626] Further improvements in presenting download links of export files --- .../Logging/LoggingExtensions.cs | 12 ++- .../201511271019577_ExportFramework3.cs | 6 ++ .../DataExchange/DataExportResult.cs | 2 +- .../DataExchange/DataExporter.cs | 23 +++-- .../Controllers/ExportController.cs | 94 ++++++++++--------- .../DataExchange/ExportDeploymentModel.cs | 9 +- .../Models/DataExchange/ExportProfileModel.cs | 12 ++- .../Views/Export/InfoDeployment.cshtml | 59 +++++++----- .../Administration/Views/Export/List.cshtml | 2 +- .../Views/Export/ProfileFileCount.cshtml | 9 +- .../Views/Export/ProfileFileDetails.cshtml | 34 +++++-- .../Views/Export/_Tab.Deployment.cshtml | 7 ++ 12 files changed, 165 insertions(+), 104 deletions(-) diff --git a/src/Libraries/SmartStore.Core/Logging/LoggingExtensions.cs b/src/Libraries/SmartStore.Core/Logging/LoggingExtensions.cs index de1266efd4..f7c2633e40 100644 --- a/src/Libraries/SmartStore.Core/Logging/LoggingExtensions.cs +++ b/src/Libraries/SmartStore.Core/Logging/LoggingExtensions.cs @@ -37,7 +37,17 @@ public static void Error(this ILogger logger, Exception exception, Customer cust FilteredLog(logger, LogLevel.Error, exception.ToAllMessages(), exception, customer); } - private static void FilteredLog(ILogger logger, LogLevel level, string message, Exception exception = null, Customer customer = null) + public static void ErrorsAll(this ILogger logger, Exception exception, Customer customer = null) + { + while (exception != null) + { + FilteredLog(logger, LogLevel.Error, exception.Message, exception, customer); + + exception = exception.InnerException; + } + } + + private static void FilteredLog(ILogger logger, LogLevel level, string message, Exception exception = null, Customer customer = null) { // don't log thread abort exception if ((exception != null) && (exception is System.Threading.ThreadAbortException)) diff --git a/src/Libraries/SmartStore.Data/Migrations/201511271019577_ExportFramework3.cs b/src/Libraries/SmartStore.Data/Migrations/201511271019577_ExportFramework3.cs index 42fe9dd04d..00ea19fba6 100644 --- a/src/Libraries/SmartStore.Data/Migrations/201511271019577_ExportFramework3.cs +++ b/src/Libraries/SmartStore.Data/Migrations/201511271019577_ExportFramework3.cs @@ -59,6 +59,12 @@ public void Seed(SmartObjectContext context) public void MigrateLocaleResources(LocaleResourcesBuilder builder) { builder.AddOrUpdate("Admin.Common.Export.PDF", "PDF Export", "PDF Export"); + builder.AddOrUpdate("Admin.Common.TemporaryFiles", "Temporary files", "Temporre Dateien"); + builder.AddOrUpdate("Admin.Common.PublicFiles", "Public files", "ffentliche Dateien"); + + builder.AddOrUpdate("Admin.Common.NoTempFilesFound", + "No temporary files were found.", + "Es wurden keine temporren Dateien gefunden."); builder.AddOrUpdate("Enums.SmartStore.Core.Domain.DataExchange.ExportEntityType.NewsLetterSubscription", "Newsletter Subscribers", diff --git a/src/Libraries/SmartStore.Services/DataExchange/DataExportResult.cs b/src/Libraries/SmartStore.Services/DataExchange/DataExportResult.cs index cfbe0db7bf..d7e0d9fa6a 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/DataExportResult.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/DataExportResult.cs @@ -29,7 +29,7 @@ public bool Succeeded /// /// Files created by last export /// - public IList Files { get; set; } + public List Files { get; set; } /// /// The path of the folder with the export files diff --git a/src/Libraries/SmartStore.Services/DataExchange/DataExporter.cs b/src/Libraries/SmartStore.Services/DataExchange/DataExporter.cs index 528bc1f1b4..9193f38739 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/DataExporter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/DataExporter.cs @@ -1135,7 +1135,7 @@ private void ExportCoreOuter(DataExporterContext ctx) } catch (Exception exception) { - logger.Error(exception); + logger.ErrorsAll(exception); ctx.Result.LastError = exception.ToString(); } finally @@ -1149,7 +1149,10 @@ private void ExportCoreOuter(DataExporterContext ctx) _exportProfileService.Value.UpdateExportProfile(ctx.Request.Profile); } } - catch { } + catch (Exception exception) + { + logger.ErrorsAll(exception); + } try { @@ -1158,7 +1161,10 @@ private void ExportCoreOuter(DataExporterContext ctx) FileSystemHelper.ClearDirectory(ctx.FolderContent, false); } } - catch { } + catch (Exception exception) + { + logger.ErrorsAll(exception); + } DetachAllEntitiesAndClear(ctx); @@ -1180,7 +1186,10 @@ private void ExportCoreOuter(DataExporterContext ctx) ctx.ExecuteContext.Log = null; ctx.Log = null; } - catch { } + catch (Exception exception) + { + logger.ErrorsAll(exception); + } } } @@ -1215,10 +1224,10 @@ private void ExportCoreOuter(DataExporterContext ctx) logger.Information("Updated order status for {0} order(s).".FormatInvariant(ctx.EntityIdsLoaded.Count())); } - catch (Exception exc) + catch (Exception exception) { - logger.Error(exc); - ctx.Result.LastError = exc.ToString(); + logger.ErrorsAll(exception); + ctx.Result.LastError = exception.ToString(); } } } diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs index 11d5681e86..b54951bcc0 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs @@ -106,21 +106,56 @@ private string GetThumbnailUrl(Provider provider) return url; } - private ExportProfileDetailsModel PrepareProfileDetailsModel(ExportProfile profile) + private ExportProfileDetailsModel PrepareProfileDetailsModel(ExportProfile profile, bool forEdit) { - var zipPath = profile.GetExportZipPath(); - var model = new ExportProfileDetailsModel { Id = profile.Id, - ZipPath = (System.IO.File.Exists(zipPath) ? zipPath : null), - ExportFiles = profile.GetExportFiles() + PublicFiles = new List() }; + try + { + var zipPath = profile.GetExportZipPath(); + + model.ZipPath = (System.IO.File.Exists(zipPath) ? zipPath : null); + model.ExportFiles = profile.GetExportFiles(); + + if (forEdit && profile.Deployments.Any(x => x.IsPublic && x.DeploymentType == ExportDeploymentType.FileSystem)) + { + var allStores = _services.StoreService.GetAllStores(); + var publicFolder = Path.Combine(HttpRuntime.AppDomainAppPath, DataExporter.PublicFolder); + var resultInfo = XmlHelper.Deserialize(profile.ResultInfo); + + if (resultInfo != null && resultInfo.Files != null) + { + foreach (var fileInfo in resultInfo.Files) + { + if (System.IO.File.Exists(Path.Combine(publicFolder, fileInfo.FileName)) && !model.PublicFiles.Any(x => x.FileName == fileInfo.FileName)) + { + var store = allStores.FirstOrDefault(y => y.Id == fileInfo.StoreId) ?? _services.StoreContext.CurrentStore; + + model.PublicFiles.Add(new ExportProfileDetailsModel.PublicFile + { + StoreId = store.Id, + StoreName = store.Name, + FileName = fileInfo.FileName, + FileUrl = string.Concat(store.Url.EnsureEndsWith("/"), DataExporter.PublicFolder.EnsureEndsWith("/"), fileInfo.FileName) + }); + } + } + } + } + } + catch (Exception exception) + { + NotifyError(exception); + } + return model; } - private void PrepareProfileModel(ExportProfileModel model, ExportProfile profile, Provider provider) + private void PrepareProfileModel(ExportProfileModel model, ExportProfile profile, Provider provider, bool forEdit) { model.Id = profile.Id; model.Name = profile.Name; @@ -141,7 +176,7 @@ private void PrepareProfileModel(ExportProfileModel model, ExportProfile profile model.Provider = new ExportProfileModel.ProviderModel(); model.Provider.ThumbnailUrl = GetThumbnailUrl(provider); - model.Details = PrepareProfileDetailsModel(profile); + model.Details = PrepareProfileDetailsModel(profile, forEdit); if (provider != null) { @@ -266,37 +301,7 @@ private void PrepareProfileModelForEdit(ExportProfileModel model, ExportProfile { var deploymentModel = PrepareDeploymentModel(x, null, false); - if (x.IsPublic) - { - try - { - var publicFolder = Path.Combine(HttpRuntime.AppDomainAppPath, DataExporter.PublicFolder); - var resultInfo = XmlHelper.Deserialize(profile.ResultInfo); - - if (resultInfo != null && resultInfo.Files != null) - { - foreach (var fileInfo in resultInfo.Files) - { - if (System.IO.File.Exists(Path.Combine(publicFolder, fileInfo.FileName)) && !deploymentModel.PublicFiles.Any(y => y.FileName == fileInfo.FileName)) - { - var store = allStores.FirstOrDefault(y => y.Id == fileInfo.StoreId) ?? _services.StoreContext.CurrentStore; - - deploymentModel.PublicFiles.Add(new ExportDeploymentModel.PublicFile - { - StoreId = store.Id, - StoreName = store.Name, - FileName = fileInfo.FileName, - FileUrl = string.Concat(store.Url.EnsureEndsWith("/"), DataExporter.PublicFolder.EnsureEndsWith("/"), fileInfo.FileName) - }); - } - } - } - } - catch (Exception exc) - { - exc.Dump(); - } - } + deploymentModel.ProfileDetails = PrepareProfileDetailsModel(profile, true); return deploymentModel; }) @@ -402,8 +407,7 @@ private ExportDeploymentModel PrepareDeploymentModel(ExportDeployment deployment EmailSubject = deployment.EmailSubject, EmailAccountId = deployment.EmailAccountId, PassiveMode = deployment.PassiveMode, - UseSsl = deployment.UseSsl, - PublicFiles = new List() + UseSsl = deployment.UseSsl }; if (forEdit) @@ -484,7 +488,7 @@ public ActionResult List() { var profileModel = new ExportProfileModel(); - PrepareProfileModel(profileModel, profile, providers.FirstOrDefault(x => x.Metadata.SystemName == profile.ProviderSystemName)); + PrepareProfileModel(profileModel, profile, providers.FirstOrDefault(x => x.Metadata.SystemName == profile.ProviderSystemName), false); profileModel.TaskModel = profile.ScheduleTask.ToScheduleTaskModel(_services.Localization, _dateTimeHelper, Url); @@ -501,7 +505,7 @@ public ActionResult ProfileListDetails(int profileId) var profile = _exportService.GetExportProfileById(profileId); if (profile != null) { - var model = PrepareProfileDetailsModel(profile); + var model = PrepareProfileDetailsModel(profile, false); return Json(new { @@ -520,7 +524,7 @@ public ActionResult ProfileFileDetails(int profileId) var profile = _exportService.GetExportProfileById(profileId); if (profile != null) { - var model = PrepareProfileDetailsModel(profile); + var model = PrepareProfileDetailsModel(profile, true); return PartialView(model); } @@ -610,7 +614,7 @@ public ActionResult Edit(int id) var model = new ExportProfileModel(); - PrepareProfileModel(model, profile, provider); + PrepareProfileModel(model, profile, provider, true); PrepareProfileModelForEdit(model, profile, provider); return View(model); @@ -631,7 +635,7 @@ public ActionResult Edit(ExportProfileModel model, bool continueEditing) if (!ModelState.IsValid) { - PrepareProfileModel(model, profile, provider); + PrepareProfileModel(model, profile, provider, true); PrepareProfileModelForEdit(model, profile, provider); return View(model); } diff --git a/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ExportDeploymentModel.cs b/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ExportDeploymentModel.cs index ffecae4f0a..6a0c317ab1 100644 --- a/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ExportDeploymentModel.cs +++ b/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ExportDeploymentModel.cs @@ -55,7 +55,6 @@ public string DeploymentTypeIconClass [SmartResourceDisplayName("Admin.DataExchange.Export.Deployment.IsPublic")] public bool IsPublic { get; set; } - public List PublicFiles { get; set; } [SmartResourceDisplayName("Admin.DataExchange.Export.Deployment.Username")] public string Username { get; set; } @@ -91,12 +90,6 @@ public string DeploymentTypeIconClass [SmartResourceDisplayName("Admin.DataExchange.Export.Deployment.UseSsl")] public bool UseSsl { get; set; } - public class PublicFile - { - public int StoreId { get; set; } - public string StoreName { get; set; } - public string FileName { get; set; } - public string FileUrl { get; set; } - } + public ExportProfileDetailsModel ProfileDetails { get; set; } } } \ No newline at end of file diff --git a/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ExportProfileModel.cs b/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ExportProfileModel.cs index b41f8fc1f5..a1a535a5f6 100644 --- a/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ExportProfileModel.cs +++ b/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ExportProfileModel.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.IO; using System.Web.Mvc; using FluentValidation.Attributes; using SmartStore.Admin.Models.Tasks; @@ -82,7 +81,6 @@ public partial class ExportProfileModel : EntityModelBase [SmartResourceDisplayName("Admin.DataExchange.Export.CloneProfile")] public int? CloneProfileId { get; set; } - //public List AvailableProfiles { get; set; } public List AvailableProfiles { get; set; } public ProviderModel Provider { get; set; } @@ -171,5 +169,15 @@ public int ExportFileCount return (ExportFiles.Count + (ZipPath.HasValue() ? 1 : 0)); } } + + public List PublicFiles { get; set; } + + public class PublicFile + { + public int StoreId { get; set; } + public string StoreName { get; set; } + public string FileName { get; set; } + public string FileUrl { get; set; } + } } } \ No newline at end of file diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Export/InfoDeployment.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Export/InfoDeployment.cshtml index 67ce817d18..fce2ac18c7 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Export/InfoDeployment.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Export/InfoDeployment.cshtml @@ -4,42 +4,51 @@ @{ Layout = null; } -

+@helper FileDownloadLink(string path, string fileName) +{ +

+ @Html.IconForFileExtension(Path.GetExtension(fileName), false) + @fileName +
+} +
 @Model.DeploymentTypeName @if (Model.DeploymentType == ExportDeploymentType.FileSystem && Model.IsPublic) { (@T("Common.Public")) } -

-@if (Model.DeploymentType == ExportDeploymentType.FileSystem) -{ - if (Model.IsPublic) +
+
+ @if (Model.DeploymentType == ExportDeploymentType.FileSystem) { - foreach (var grp in Model.PublicFiles.OrderBy(x => x.StoreId).GroupBy(x => x.StoreId)) + foreach (var path in Model.ProfileDetails.ExportFiles) + { + @FileDownloadLink(path, Path.GetFileName(path)) + } + + if (Model.ProfileDetails.PublicFiles.Count > 0) { -

+ foreach (var grp in Model.ProfileDetails.PublicFiles.OrderBy(x => x.StoreId).GroupBy(x => x.StoreId)) + { +

@(grp.First().StoreName):
- @foreach (var file in grp) + foreach (var file in grp) { - + } -

+ } } } - else + else if (Model.DeploymentType == ExportDeploymentType.Email) { -
@Model.FileSystemPath
+
@Model.EmailAddresses
} -} -else if (Model.DeploymentType == ExportDeploymentType.Email) -{ -
@Model.EmailAddresses
-} -else if (Model.DeploymentType == ExportDeploymentType.Http) -{ -
@Model.Url
-} -else if (Model.DeploymentType == ExportDeploymentType.Ftp) -{ -
@Model.Url
-} + else if (Model.DeploymentType == ExportDeploymentType.Http) + { +
@Model.Url
+ } + else if (Model.DeploymentType == ExportDeploymentType.Ftp) + { +
@Model.Url
+ } +
\ No newline at end of file diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Export/List.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Export/List.cshtml index c1e1a0beb3..9ddcf27347 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Export/List.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Export/List.cshtml @@ -131,7 +131,7 @@ else
- @@ -266,22 +244,6 @@ $('#SearchManufacturerIdContainer').toggle(_.isEmpty($(this).val())); }).trigger('change'); - // export products to pdf - $('a.pdf-export-button').click(function (e) { - e.preventDefault(); - - if (confirm('@T("Admin.Common.AskToProceed")')) { - var form = '
'; - form += ''; - form += '
'; - - $('body').append(form); - $('#PdfExportForm').submit(); - } - - return false; - }); - $('#mastercheckbox').click(function () { $('.checkboxGroups').attr('checked', $(this).is(':checked')).change(); }); diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Product/PdfCatalog.Print.Cover.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Product/PdfCatalog.Print.Cover.cshtml deleted file mode 100644 index 4cfae9aa79..0000000000 --- a/src/Presentation/SmartStore.Web/Administration/Views/Product/PdfCatalog.Print.Cover.cshtml +++ /dev/null @@ -1,35 +0,0 @@ -@model PrintableProductsModel -@using SmartStore.Core.Html; -@{ - Layout = "~/Views/Shared/_Print.cshtml"; -} - - - -
- - @Html.Widget("pdfcatalog_cover_top") - - @if (Model.PrintLogoUrl.HasValue()) - { -
- -
-
- } - - @Html.Widget("pdfcatalog_cover_logo_after") - -

@Model.StoreName

- - @Html.Widget("pdfcatalog_cover_storename_after") - -
- @Html.Action("PdfReceiptFooter", "Common", new { area = "", isPartial = true }) -
- -
diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Product/PdfCatalog.Print.Footer.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Product/PdfCatalog.Print.Footer.cshtml deleted file mode 100644 index 69d906f865..0000000000 --- a/src/Presentation/SmartStore.Web/Administration/Views/Product/PdfCatalog.Print.Footer.cshtml +++ /dev/null @@ -1,19 +0,0 @@ -@model PrintableProductsModel -@using SmartStore.Web.Framework.Pdf; -@{ - Layout = null; -} - - - -
- -
-
- von -
-
- @Model.StoreName -
-
- diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Product/PdfCatalog.Print.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Product/PdfCatalog.Print.cshtml deleted file mode 100644 index cd81040195..0000000000 --- a/src/Presentation/SmartStore.Web/Administration/Views/Product/PdfCatalog.Print.cshtml +++ /dev/null @@ -1,187 +0,0 @@ -@model PrintableProductsModel -@using SmartStore.Core.Domain.Orders; -@using SmartStore.Core.Domain.Catalog; -@using SmartStore.Admin.Models.Shipping; -@using SmartStore.Services.Localization; -@using SmartStore.Core.Html; -@{ - - Layout = "~/Views/Shared/_Print.cshtml"; - - //title - Html.AddTitleParts(Model.StoreName); -} - -
- @foreach (var product in Model.Products) - { -
- @Html.Widget("pdfcatalog_productdetail_top") -

@product.Name

-

- @product.ShortDescription -

- -
- - @if (!String.IsNullOrEmpty(product.Sku)) { - - - - - } - @if (!String.IsNullOrEmpty(product.Price)) - { - - - - - } - @if (!String.IsNullOrEmpty(product.Manufacturer)) - { - - - - - } - @if (!String.IsNullOrEmpty(product.Weight)) - { - - - - - } - @if (!String.IsNullOrEmpty(product.Length)) - { - - - - - } - @if (!String.IsNullOrEmpty(product.Width)) - { - - - - - } - @if (!String.IsNullOrEmpty(product.Height)) - { - - - - - } -
- @T("PDFProductCatalog.SKU"): - - @product.Sku -
- @T("PDFProductCatalog.Price"): - - @product.Price -
- @T("PDFProductCatalog.Manufacturer"): - - @product.Manufacturer -
- @T("PDFProductCatalog.Weight"): - - @product.Weight -
- @T("PDFProductCatalog.Length"): - - @product.Length -
- @T("PDFProductCatalog.Width"): - - @product.Width -
- @T("PDFProductCatalog.Height"): - - @product.Height -
-
- - @if (product.PictureUrl.HasValue()) - { -
- -
- } - - @Html.Widget("pdfcatalog_productdetail_fulldescription_before") - -

- @Html.Raw(product.FullDescription) -

- - @Html.Widget("pdfcatalog_productdetail_picture_before") - - @if(product.SpecificationAttributes.Count > 0) - { - @Html.Widget("pdfcatalog_productdetail_specificationattributes_before") - -

@T("PDFProductCatalog.SpecificationAttributes")

- - @foreach (var specattr in product.SpecificationAttributes) - { - - - - - } -
- @specattr.SpecificationAttributeName : - - @specattr.SpecificationAttributeOption -
- } - - @if(product.BundledItems.Count > 0) - { -
- @Html.Widget("pdfcatalog_productdetail_bundleditems_before") -

@T("PDFProductCatalog.BundledItems")

- foreach (var bundleProduct in product.BundledItems) - { -
-
- -
-
- @bundleProduct.Name -
- @bundleProduct.ShortDescription -
- -
- } - -
- } - - @if (product.AssociatedProducts.Count > 0) - { -
- @Html.Widget("pdfcatalog_productdetail_associatedproducts_before") -

@T("PDFProductCatalog.AssociatedProducts")

- foreach (var groupedProduct in product.AssociatedProducts) - { -
-
- -
-
- @groupedProduct.Name -
- @groupedProduct.ShortDescription -
-
- } -
- } - -
- } -
diff --git a/src/Presentation/SmartStore.Web/Controllers/OrderController.cs b/src/Presentation/SmartStore.Web/Controllers/OrderController.cs index b4b1976c25..671e9f38db 100644 --- a/src/Presentation/SmartStore.Web/Controllers/OrderController.cs +++ b/src/Presentation/SmartStore.Web/Controllers/OrderController.cs @@ -568,28 +568,36 @@ public ActionResult PrintMany(string ids = null, bool pdf = false) if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageOrders)) return new HttpUnauthorizedResult(); - IList orders; + const int maxOrders = 500; + IList orders = null; + int totalCount = 0; using (var scope = new DbContextScope(_services.DbContext, autoDetectChanges: false, forceNoTracking: true)) { if (ids != null) { - int[] intIds = ids.ToIntArray(); - orders = _orderService.GetOrdersByIds(intIds); + orders = _orderService.GetOrdersByIds(ids.ToIntArray()); + totalCount = orders.Count; } else { - orders = _orderService.SearchOrders(0, 0, null, null, null, null, null, null, null, null, 0, int.MaxValue); + var pagedOrders = _orderService.SearchOrders(0, 0, null, null, null, null, null, null, null, null, 0, 1); + totalCount = pagedOrders.TotalCount; + + if (totalCount > 0 && totalCount <= maxOrders) + { + orders = _orderService.SearchOrders(0, 0, null, null, null, null, null, null, null, null, 0, int.MaxValue); + } } } - if (orders.Count == 0) + if (totalCount == 0) { NotifyInfo(T("Admin.Common.ExportNoData")); return RedirectToReferrer(); } - if (orders.Count > 500) + if (totalCount > maxOrders) { NotifyWarning(T("Admin.Common.ExportToPdf.TooManyItems")); return RedirectToReferrer(); From a558b3582486d02ebdd80072d9acd813527e67f6 Mon Sep 17 00:00:00 2001 From: Murat Cakir Date: Tue, 8 Dec 2015 21:29:38 +0100 Subject: [PATCH 068/626] Added ImportDataSegmenter.GetColumnIndexes() method --- .../Import/ImportDataSegmenter.cs | 42 ++++++++++++++++++- .../DataExchange/Import/ImportRow.cs | 14 ++----- .../DataExchange/ImportDataSegmenterTests.cs | 42 +++++++++++++++++++ .../SmartStore.Services.Tests.csproj | 1 + 4 files changed, 87 insertions(+), 12 deletions(-) create mode 100644 src/Tests/SmartStore.Services.Tests/DataExchange/ImportDataSegmenterTests.cs diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportDataSegmenter.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportDataSegmenter.cs index 8a566dfbb8..4bcb355089 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportDataSegmenter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportDataSegmenter.cs @@ -12,13 +12,15 @@ public class ImportDataSegmenter where T : BaseEntity { private const int BATCHSIZE = 100; - private IDataTable _table; + private readonly IDataTable _table; private ImportRow[] _currentBatch; - private IPageable _pageable; + private readonly IPageable _pageable; private bool _bof; private CultureInfo _culture; private ColumnMap _columnMap; + private readonly IDictionary _columnIndexes = new Dictionary(StringComparer.OrdinalIgnoreCase); + public ImportDataSegmenter(IDataTable table) { Guard.ArgumentNotNull(() => table); @@ -95,6 +97,42 @@ public bool HasDataColumn(string name, string index) return _table.HasColumn(_columnMap.GetMappedName(name, index)); } + /// + /// Returns an array of exisiting index names for a column + /// + /// The name of the columns without index qualification + /// An array of index names + /// + /// If following columns exist in source: Attr[Color], Attr[Size] + /// This method returns: string[] { "Color", "Size" } + /// + public string[] GetColumnIndexes(string name) + { + string[] indexes; + + if (!_columnIndexes.TryGetValue(name, out indexes)) + { + var startsWith = name + "["; + + var columns1 = _columnMap.Mappings + .Where(x => x.Key.StartsWith(startsWith, StringComparison.OrdinalIgnoreCase)) + .Select(x => x.Key); + + var columns2 = _table.Columns + .Where(x => x.Name.StartsWith(startsWith, StringComparison.OrdinalIgnoreCase)) + .Select(x => x.Name); + + indexes = columns1.Concat(columns2) + .Distinct(StringComparer.OrdinalIgnoreCase) + .Select(x => x.Substring(x.IndexOf("[", StringComparison.OrdinalIgnoreCase) + 1).TrimEnd(']')) + .ToArray(); + + _columnIndexes[name] = indexes; + } + + return indexes; + } + public void Reset() { if (_pageable.PageIndex != 0 && _currentBatch != null) diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportRow.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportRow.cs index b1ebde7e70..9ca5ab441b 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportRow.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportRow.cs @@ -14,7 +14,7 @@ public class ImportRow where T : BaseEntity private bool _initialized = false; private T _entity; private string _entityDisplayName; - private int _position; + private readonly int _position; private bool _isNew; private ImportRowInfo _rowInfo; @@ -130,15 +130,9 @@ public bool SetProperty( } else { - if (value.ToString().ToUpper().Equals("NULL")) - { - // prop is set "explicitly" to null. - converted = default(TProp); - } - else - { - converted = value.Convert(_segmenter.Culture); - } + converted = value.ToString().ToUpper().Equals("NULL") + ? default(TProp) + : value.Convert(_segmenter.Culture); } fastProp.SetValue(target, converted); diff --git a/src/Tests/SmartStore.Services.Tests/DataExchange/ImportDataSegmenterTests.cs b/src/Tests/SmartStore.Services.Tests/DataExchange/ImportDataSegmenterTests.cs new file mode 100644 index 0000000000..ceb0fb3d93 --- /dev/null +++ b/src/Tests/SmartStore.Services.Tests/DataExchange/ImportDataSegmenterTests.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using NUnit.Framework; +using SmartStore.Core.Domain.Catalog; +using SmartStore.Services.DataExchange.Import; +using SmartStore.Tests; + +namespace SmartStore.Services.Tests.DataExchange +{ + [TestFixture] + public class ImportDataSegmenterTests + { + [Test] + public void CanResolveColumnIndexNames() + { + var columns = new List + { + new LightweightDataColumn("Attr[Color]", typeof(string)), + new LightweightDataColumn("Attr[Size]", typeof(string)), + new LightweightDataColumn("material", typeof(string)), + new LightweightDataColumn("Name[en]", typeof(string)), + new LightweightDataColumn("Name[de]", typeof(string)), + new LightweightDataColumn("Name[fr]", typeof(string)), + new LightweightDataColumn("name_it", typeof(string)), + }; + + var table = new LightweightDataTable(columns, new List()); + var segmenter = new ImportDataSegmenter(table); + segmenter.ColumnMap.AddMapping("Attr[Material]", "material"); + segmenter.ColumnMap.AddMapping("Name[it]", "name_it"); + + var attrs = segmenter.GetColumnIndexes("Attr"); + attrs.ShouldSequenceEqual(new string[] {"Material", "Color", "Size"}); + + var langs = segmenter.GetColumnIndexes("Name"); + langs.ShouldSequenceEqual(new string[] { "it", "en", "de", "fr" }); + } + } +} diff --git a/src/Tests/SmartStore.Services.Tests/SmartStore.Services.Tests.csproj b/src/Tests/SmartStore.Services.Tests/SmartStore.Services.Tests.csproj index 1780542acc..a507b19eb5 100644 --- a/src/Tests/SmartStore.Services.Tests/SmartStore.Services.Tests.csproj +++ b/src/Tests/SmartStore.Services.Tests/SmartStore.Services.Tests.csproj @@ -106,6 +106,7 @@ + From 37eecc1bc5580bfc97264b5a96fac83106feb4cb Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Wed, 9 Dec 2015 11:20:25 +0100 Subject: [PATCH 069/626] Display ID for primary entities on backend edit page --- .../Views/Category/_CreateOrUpdate.cshtml | 24 ++++++++++++++++--- .../Views/Customer/_CreateOrUpdate.cshtml | 14 ++++++++++- .../Views/Manufacturer/_CreateOrUpdate.cshtml | 22 +++++++++++++++-- .../Views/Product/_CreateOrUpdate.Info.cshtml | 4 ++-- 4 files changed, 56 insertions(+), 8 deletions(-) diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Category/_CreateOrUpdate.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Category/_CreateOrUpdate.cshtml index 9f98f0d5a0..78b0bc549f 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Category/_CreateOrUpdate.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Category/_CreateOrUpdate.cshtml @@ -14,8 +14,25 @@ //generate an event EngineContext.Current.Resolve().Publish(new TabStripCreated(x, "category-edit", this.Html, this.Model)); }) -@helper TabInfo() { - +@helper TabInfo() +{ + if (Model.Id != 0) + { + + + + + +
+ @Html.SmartLabelFor(model => model.Id) + + @Html.DisplayFor(model => model.Id) + @Html.ValidationMessageFor(model => model.Id) +
+ +

+ } + @(Html.LocalizedEditor("category-info-localized", @ @@ -99,7 +116,8 @@
- )) +)) +
diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Customer/_CreateOrUpdate.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Customer/_CreateOrUpdate.cshtml index 090c3da2d5..dee81edee0 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Customer/_CreateOrUpdate.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Customer/_CreateOrUpdate.cshtml @@ -36,7 +36,7 @@ EngineContext.Current.Resolve().Publish(new TabStripCreated(x, "customer-edit", this.Html, this.Model)); }) @helper TabInfo() - { +{ if (Model.CountryEnabled && Model.StateProvinceEnabled) { } + @if (Model.Id != 0) + { + + + + + } @if (Model.UsernamesEnabled) { if (Model.Id == 0 || Model.AllowUsersToChangeUsernames) diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Manufacturer/_CreateOrUpdate.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Manufacturer/_CreateOrUpdate.cshtml index 44385835cb..8b0c80c9ac 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Manufacturer/_CreateOrUpdate.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Manufacturer/_CreateOrUpdate.cshtml @@ -15,7 +15,24 @@ EngineContext.Current.Resolve().Publish(new TabStripCreated(x, "manufacturer-edit", this.Html, this.Model)); }) @helper TabInfo() - { +{ + if (Model.Id != 0) + { +
+ @Html.SmartLabelFor(model => model.Id) + + @Html.DisplayFor(model => model.Id) + @Html.ValidationMessageFor(model => model.Id) +
+ + + + +
+ @Html.SmartLabelFor(model => model.Id) + + @Html.DisplayFor(model => model.Id) + @Html.ValidationMessageFor(model => model.Id) +
+ +

+ } + @(Html.LocalizedEditor("manufacturer-info-localized", @ @@ -63,7 +80,8 @@
- )) +)) + - + @@ -45,10 +45,10 @@ @Html.SymbolForBool(profile.Enabled) - - + @@ -332,7 +331,6 @@ - + + + +
diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Product/_CreateOrUpdate.Info.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Product/_CreateOrUpdate.Info.cshtml index 8b4f0e6dba..9352203d40 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Product/_CreateOrUpdate.Info.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Product/_CreateOrUpdate.Info.cshtml @@ -191,14 +191,14 @@
- @if (Model.Id > 0) + @if (Model.Id != 0) { From 09ad4aa3641768ace64de481d4960bf8896dff01 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Wed, 9 Dec 2015 17:17:03 +0100 Subject: [PATCH 070/626] Initial implementation of import framework --- .../Domain/DataExchange/ImportProfile.cs | 62 +++++ .../SmartStore.Core/SmartStore.Core.csproj | 1 + .../Mapping/DataExchange/ImportProfileMap.cs | 25 ++ .../201508091512101_ExportFramework.cs | 19 +- ...01512091408315_ImportFramework.Designer.cs | 29 +++ .../201512091408315_ImportFramework.cs | 109 +++++++++ .../201512091408315_ImportFramework.resx | 126 ++++++++++ .../SmartStore.Data/SmartStore.Data.csproj | 8 + .../DataExchange/ExportProfileService.cs | 4 - .../DataExchange/Import/DataImportTask.cs | 17 ++ .../Import/IImportProfileService.cs | 42 ++++ .../DataExchange/Import/ImportExtensions.cs | 55 +++++ .../Import/ImportProfileService.cs | 124 ++++++++++ .../Security/StandardPermissionProvider.cs | 3 + .../SmartStore.Services.csproj | 4 + .../DependencyRegistrar.cs | 1 + .../Controllers/ImportController.cs | 218 ++++++++++++++++++ .../Models/DataExchange/ExportProfileModel.cs | 8 +- .../Models/DataExchange/ImportProfileModel.cs | 46 ++++ .../Administration/SmartStore.Admin.csproj | 4 + .../DataExchange/ImportProfileValidator.cs | 22 ++ .../Administration/Views/Export/List.cshtml | 2 +- .../Administration/Views/Import/List.cshtml | 167 ++++++++++++++ .../Administration/sitemap.config | 1 + 24 files changed, 1068 insertions(+), 29 deletions(-) create mode 100644 src/Libraries/SmartStore.Core/Domain/DataExchange/ImportProfile.cs create mode 100644 src/Libraries/SmartStore.Data/Mapping/DataExchange/ImportProfileMap.cs create mode 100644 src/Libraries/SmartStore.Data/Migrations/201512091408315_ImportFramework.Designer.cs create mode 100644 src/Libraries/SmartStore.Data/Migrations/201512091408315_ImportFramework.cs create mode 100644 src/Libraries/SmartStore.Data/Migrations/201512091408315_ImportFramework.resx create mode 100644 src/Libraries/SmartStore.Services/DataExchange/Import/DataImportTask.cs create mode 100644 src/Libraries/SmartStore.Services/DataExchange/Import/IImportProfileService.cs create mode 100644 src/Libraries/SmartStore.Services/DataExchange/Import/ImportExtensions.cs create mode 100644 src/Libraries/SmartStore.Services/DataExchange/Import/ImportProfileService.cs create mode 100644 src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs create mode 100644 src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ImportProfileModel.cs create mode 100644 src/Presentation/SmartStore.Web/Administration/Validators/DataExchange/ImportProfileValidator.cs create mode 100644 src/Presentation/SmartStore.Web/Administration/Views/Import/List.cshtml diff --git a/src/Libraries/SmartStore.Core/Domain/DataExchange/ImportProfile.cs b/src/Libraries/SmartStore.Core/Domain/DataExchange/ImportProfile.cs new file mode 100644 index 0000000000..38633e4fed --- /dev/null +++ b/src/Libraries/SmartStore.Core/Domain/DataExchange/ImportProfile.cs @@ -0,0 +1,62 @@ +using SmartStore.Core.Domain.Tasks; + +namespace SmartStore.Core.Domain +{ + public class ImportProfile : BaseEntity + { + /// + /// The name of the profile + /// + public string Name { get; set; } + + /// + /// The name of the folder (file system) + /// + public string FolderName { get; set; } + + /// + /// The type of the entity + /// + public string EntityType { get; set; } + + /// + /// Whether the profile is enabled + /// + public bool Enabled { get; set; } + + /// + /// Number of records to bypass + /// + public int Skip { get; set; } + + /// + /// Maximum number of records to return + /// + public int Take { get; set; } + + /// + /// File type specific configuration + /// + public string FileTypeConfiguration { get; set; } + + /// + /// Mapping of import columns + /// + public string ColumnMapping { get; set; } + + /// + /// Whether to delete import files after import + /// + public bool Cleanup { get; set; } + + /// + /// The scheduling task identifier + /// + public int SchedulingTaskId { get; set; } + + /// + /// The scheduling task + /// + public virtual ScheduleTask ScheduleTask { get; set; } + } +} diff --git a/src/Libraries/SmartStore.Core/SmartStore.Core.csproj b/src/Libraries/SmartStore.Core/SmartStore.Core.csproj index 96cdf8c400..e876d7b408 100644 --- a/src/Libraries/SmartStore.Core/SmartStore.Core.csproj +++ b/src/Libraries/SmartStore.Core/SmartStore.Core.csproj @@ -168,6 +168,7 @@ + diff --git a/src/Libraries/SmartStore.Data/Mapping/DataExchange/ImportProfileMap.cs b/src/Libraries/SmartStore.Data/Mapping/DataExchange/ImportProfileMap.cs new file mode 100644 index 0000000000..94b9d9a46a --- /dev/null +++ b/src/Libraries/SmartStore.Data/Mapping/DataExchange/ImportProfileMap.cs @@ -0,0 +1,25 @@ +using System.Data.Entity.ModelConfiguration; +using SmartStore.Core.Domain; + +namespace SmartStore.Data.Mapping.DataExchange +{ + public partial class ImportProfileMap : EntityTypeConfiguration + { + public ImportProfileMap() + { + this.ToTable("ImportProfile"); + this.HasKey(x => x.Id); + + this.Property(x => x.Name).IsRequired().HasMaxLength(100); + this.Property(x => x.FolderName).IsRequired().HasMaxLength(100); + this.Property(x => x.EntityType).IsRequired().HasMaxLength(100); + this.Property(x => x.FileTypeConfiguration).IsMaxLength(); + this.Property(x => x.ColumnMapping).IsMaxLength(); + + this.HasRequired(x => x.ScheduleTask) + .WithMany() + .HasForeignKey(x => x.SchedulingTaskId) + .WillCascadeOnDelete(false); + } + } +} diff --git a/src/Libraries/SmartStore.Data/Migrations/201508091512101_ExportFramework.cs b/src/Libraries/SmartStore.Data/Migrations/201508091512101_ExportFramework.cs index 64bb41f4d8..74f4c865d7 100644 --- a/src/Libraries/SmartStore.Data/Migrations/201508091512101_ExportFramework.cs +++ b/src/Libraries/SmartStore.Data/Migrations/201508091512101_ExportFramework.cs @@ -142,24 +142,7 @@ public void MigrateLocaleResources(LocaleResourcesBuilder builder) "The file type of the exported data.", "Der Dateityp der exportierten Daten."); - builder.AddOrUpdate("Admin.DataExchange.Export.LastExecution", - "Last execution", - "Letzte Ausfhrung", - "Information about the last execution of the export.", - "Informationen zur letzten Ausfhrung des Exports."); - - - builder.AddOrUpdate("Admin.DataExchange.Export.Offset", - "Skip", - "berspringen", - "Specifies the number of records to be skipped.", - "Legt die Anzahl der zu berspringenden Datenstze fest."); - - builder.AddOrUpdate("Admin.DataExchange.Export.Limit", - "Limit", - "Begrenzen", - "Specifies how many records to be loaded at maximum.", - "Legt die maximale Anzahl der zu exportierenden Datenstze fest."); + builder.AddOrUpdate("Admin.DataExchange.Export.BatchSize", "Batch size", diff --git a/src/Libraries/SmartStore.Data/Migrations/201512091408315_ImportFramework.Designer.cs b/src/Libraries/SmartStore.Data/Migrations/201512091408315_ImportFramework.Designer.cs new file mode 100644 index 0000000000..2d56b77d1e --- /dev/null +++ b/src/Libraries/SmartStore.Data/Migrations/201512091408315_ImportFramework.Designer.cs @@ -0,0 +1,29 @@ +// +namespace SmartStore.Data.Migrations +{ + using System.CodeDom.Compiler; + using System.Data.Entity.Migrations; + using System.Data.Entity.Migrations.Infrastructure; + using System.Resources; + + [GeneratedCode("EntityFramework.Migrations", "6.1.3-40302")] + public sealed partial class ImportFramework : IMigrationMetadata + { + private readonly ResourceManager Resources = new ResourceManager(typeof(ImportFramework)); + + string IMigrationMetadata.Id + { + get { return "201512091408315_ImportFramework"; } + } + + string IMigrationMetadata.Source + { + get { return null; } + } + + string IMigrationMetadata.Target + { + get { return Resources.GetString("Target"); } + } + } +} diff --git a/src/Libraries/SmartStore.Data/Migrations/201512091408315_ImportFramework.cs b/src/Libraries/SmartStore.Data/Migrations/201512091408315_ImportFramework.cs new file mode 100644 index 0000000000..06901ed24c --- /dev/null +++ b/src/Libraries/SmartStore.Data/Migrations/201512091408315_ImportFramework.cs @@ -0,0 +1,109 @@ +namespace SmartStore.Data.Migrations +{ + using System.Data.Entity.Migrations; + using Core.Domain.Customers; + using Core.Domain.Security; + using Setup; + + public partial class ImportFramework : DbMigration, ILocaleResourcesProvider, IDataSeeder + { + public override void Up() + { + CreateTable( + "dbo.ImportProfile", + c => new + { + Id = c.Int(nullable: false, identity: true), + Name = c.String(nullable: false, maxLength: 100), + FolderName = c.String(nullable: false, maxLength: 100), + EntityType = c.String(nullable: false, maxLength: 100), + Enabled = c.Boolean(nullable: false), + Skip = c.Int(nullable: false), + Take = c.Int(nullable: false), + FileTypeConfiguration = c.String(), + ColumnMapping = c.String(), + Cleanup = c.Boolean(nullable: false), + SchedulingTaskId = c.Int(nullable: false), + }) + .PrimaryKey(t => t.Id) + .ForeignKey("dbo.ScheduleTask", t => t.SchedulingTaskId) + .Index(t => t.SchedulingTaskId); + + } + + public override void Down() + { + DropForeignKey("dbo.ImportProfile", "SchedulingTaskId", "dbo.ScheduleTask"); + DropIndex("dbo.ImportProfile", new[] { "SchedulingTaskId" }); + DropTable("dbo.ImportProfile"); + } + + public bool RollbackOnFailure + { + get { return false; } + } + + public void Seed(SmartObjectContext context) + { + context.MigrateLocaleResources(MigrateLocaleResources); + + var permissionMigrator = new PermissionMigrator(context); + + permissionMigrator.AddPermission(new PermissionRecord + { + Name = "Admin area. Manage Imports", + SystemName = "ManageImports", + Category = "Configuration" + }, new string[] { SystemCustomerRoleNames.Administrators }); + } + + public void MigrateLocaleResources(LocaleResourcesBuilder builder) + { + builder.AddOrUpdate("Common.Files", "Files", "Dateien"); + + builder.AddOrUpdate("Admin.Common.RecordsSkip", + "Skip", + "berspringen", + "Specifies the number of records to be skipped.", + "Legt die Anzahl der zu berspringenden Datenstze fest."); + + builder.AddOrUpdate("Admin.Common.RecordsTake", + "Limit", + "Begrenzen", + "Specifies the maximum number of records to be processed.", + "Legt die maximale Anzahl der zu verarbeitenden Datenstze fest."); + + builder.AddOrUpdate("Admin.DataExchange.Import.NoProfiles", + "There were no import profiles found.", + "Es wurden keine Importprofile gefunden."); + + builder.AddOrUpdate("Admin.DataExchange.Import.FolderName.Validate", + "Please enter a valid folder name.", + "Bitte einen gltigen Ordnernamen eingeben."); + + builder.AddOrUpdate("Admin.DataExchange.Import.Name", + "Name of profile", + "Name des Profils", + "Specifies the name of the import profile.", + "Legt den Namen des Importprofils fest."); + + builder.AddOrUpdate("Admin.DataExchange.Import.FolderName", + "Folder name", + "Ordnername", + "Specifies the name of the folder where the import files are saved.", + "Legt den Namen des Ordners fest, in den die Importdateien gespeichert werden."); + + builder.AddOrUpdate("Admin.DataExchange.Import.Cleanup", + "Clean up at the end", + "Zum Schluss aufrumen", + "Specifies whether to delete import files after an import.", + "Legt fest, ob die Importdateien nach einem Import gelscht werden sollen."); + + builder.Delete( + "Admin.DataExchange.Export.LastExecution", + "Admin.DataExchange.Export.Offset", + "Admin.DataExchange.Export.Limit" + ); + } + } +} diff --git a/src/Libraries/SmartStore.Data/Migrations/201512091408315_ImportFramework.resx b/src/Libraries/SmartStore.Data/Migrations/201512091408315_ImportFramework.resx new file mode 100644 index 0000000000..bf924882bc --- /dev/null +++ b/src/Libraries/SmartStore.Data/Migrations/201512091408315_ImportFramework.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 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 + + + dbo + + \ No newline at end of file diff --git a/src/Libraries/SmartStore.Data/SmartStore.Data.csproj b/src/Libraries/SmartStore.Data/SmartStore.Data.csproj index 7e8cce3347..aee5f01421 100644 --- a/src/Libraries/SmartStore.Data/SmartStore.Data.csproj +++ b/src/Libraries/SmartStore.Data/SmartStore.Data.csproj @@ -121,6 +121,7 @@ + @@ -371,6 +372,10 @@ 201511271019577_ExportFramework3.cs + + + 201512091408315_ImportFramework.cs + @@ -694,6 +699,9 @@ 201511271019577_ExportFramework3.cs + + 201512091408315_ImportFramework.cs + diff --git a/src/Libraries/SmartStore.Services/DataExchange/ExportProfileService.cs b/src/Libraries/SmartStore.Services/DataExchange/ExportProfileService.cs index 3f2314afb1..53776a31c7 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/ExportProfileService.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/ExportProfileService.cs @@ -45,8 +45,6 @@ public ExportProfileService( _localizationService = localizationService; } - #region Export profiles - public virtual ExportProfile InsertExportProfile( string providerSystemName, string name, @@ -340,7 +338,5 @@ public virtual void DeleteExportDeployment(ExportDeployment deployment) _eventPublisher.EntityDeleted(deployment); } - - #endregion } } diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/DataImportTask.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/DataImportTask.cs new file mode 100644 index 0000000000..ad4a21785b --- /dev/null +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/DataImportTask.cs @@ -0,0 +1,17 @@ +using SmartStore.Services.Tasks; + +namespace SmartStore.Services.DataExchange.Import +{ + // note: namespace persisted in ScheduleTask.Type + public partial class DataImportTask : ITask + { + public DataImportTask() + { + } + + public void Execute(TaskExecutionContext ctx) + { + // TODO + } + } +} diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/IImportProfileService.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/IImportProfileService.cs new file mode 100644 index 0000000000..85d6f64dec --- /dev/null +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/IImportProfileService.cs @@ -0,0 +1,42 @@ +using System.Linq; +using SmartStore.Core.Domain; + +namespace SmartStore.Services.DataExchange.Import +{ + public interface IImportProfileService + { + /// + /// Inserts an import profile + /// + /// Profile name + /// + /// Inserted import profile + ImportProfile InsertImportProfile(string name, string entityType); + + /// + /// Updates an import profile + /// + /// Import profile + void UpdateImportProfile(ImportProfile profile); + + /// + /// Deletes an import profile + /// + /// Import profile + void DeleteImportProfile(ImportProfile profile); + + /// + /// Get queryable import profiles + /// + /// Whether to filter enabled or disabled profiles + /// Import profiles + IQueryable GetImportProfiles(bool? enabled = null); + + /// + /// Gets an import profile by identifier + /// + /// Import profile identifier + /// Import profile + ImportProfile GetImportProfileById(int id); + } +} diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportExtensions.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportExtensions.cs new file mode 100644 index 0000000000..078a04a460 --- /dev/null +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportExtensions.cs @@ -0,0 +1,55 @@ +using System.Collections.Generic; +using System.IO; +using System.Linq; +using SmartStore.Core.Domain; +using SmartStore.Utilities; + +namespace SmartStore.Services.DataExchange.Import +{ + public static class ImportExtensions + { + /// + /// Get folder for import files + /// + /// Import profile + /// Folder path + public static string GetImportFolder(this ImportProfile profile, bool content = false, bool create = false) + { + var path = CommonHelper.MapPath(string.Concat("~/App_Data/ImportProfiles/", profile.FolderName, content ? "/Content" : "")); + + if (create && !System.IO.Directory.Exists(path)) + System.IO.Directory.CreateDirectory(path); + + return path; + } + + /// + /// Gets import files for an import profile + /// + /// Import profile + /// List of file paths + public static List GetImportFiles(this ImportProfile profile) + { + var folder = profile.GetImportFolder(true); + + if (System.IO.Directory.Exists(folder)) + { + return System.IO.Directory.EnumerateFiles(folder, "*", SearchOption.TopDirectoryOnly) + .OrderBy(x => x) + .ToList(); + } + + return new List(); + } + + /// + /// Get log file path for an import profile + /// + /// Import profile + /// Log file path + public static string GetImportLogPath(this ImportProfile profile) + { + return Path.Combine(profile.GetImportFolder(), "log.txt"); + } + } +} diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportProfileService.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportProfileService.cs new file mode 100644 index 0000000000..76f7a0b083 --- /dev/null +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportProfileService.cs @@ -0,0 +1,124 @@ +using System; +using System.Linq; +using SmartStore.Core.Data; +using SmartStore.Core.Domain; +using SmartStore.Core.Domain.DataExchange; +using SmartStore.Core.Domain.Tasks; +using SmartStore.Core.Events; +using SmartStore.Services.Tasks; +using SmartStore.Utilities; + +namespace SmartStore.Services.DataExchange.Import +{ + public partial class ImportProfileService : IImportProfileService + { + private readonly IRepository _importProfileRepository; + private readonly IEventPublisher _eventPublisher; + private readonly IScheduleTaskService _scheduleTaskService; + private readonly DataExchangeSettings _dataExchangeSettings; + + public ImportProfileService( + IRepository importProfileRepository, + IEventPublisher eventPublisher, + IScheduleTaskService scheduleTaskService, + DataExchangeSettings dataExchangeSettings) + { + _importProfileRepository = importProfileRepository; + _eventPublisher = eventPublisher; + _scheduleTaskService = scheduleTaskService; + _dataExchangeSettings = dataExchangeSettings; + } + + public virtual ImportProfile InsertImportProfile(string name, string entityType) + { + Guard.ArgumentNotEmpty(() => name); + Guard.ArgumentNotEmpty(() => entityType); + + var task = new ScheduleTask + { + CronExpression = "0 */24 * * *", + Type = typeof(DataImportTask).AssemblyQualifiedNameWithoutVersion(), + Enabled = false, + StopOnError = false, + IsHidden = true + }; + + task.Name = string.Concat(name, " Task"); + + _scheduleTaskService.InsertTask(task); + + var profile = new ImportProfile + { + Name = name, + EntityType = entityType, + Enabled = true, + SchedulingTaskId = task.Id + }; + + profile.FolderName = SeoHelper.GetSeName(name, true, false) + .ToValidPath() + .Truncate(_dataExchangeSettings.MaxFileNameLength); + + _importProfileRepository.Insert(profile); + + task.Alias = profile.Id.ToString(); + _scheduleTaskService.UpdateTask(task); + + _eventPublisher.EntityInserted(profile); + + return profile; + } + + public virtual void UpdateImportProfile(ImportProfile profile) + { + if (profile == null) + throw new ArgumentNullException("profile"); + + _importProfileRepository.Update(profile); + + _eventPublisher.EntityUpdated(profile); + } + + public virtual void DeleteImportProfile(ImportProfile profile) + { + if (profile == null) + throw new ArgumentNullException("profile"); + + int scheduleTaskId = profile.SchedulingTaskId; + + _importProfileRepository.Delete(profile); + + var scheduleTask = _scheduleTaskService.GetTaskById(scheduleTaskId); + _scheduleTaskService.DeleteTask(scheduleTask); + + _eventPublisher.EntityDeleted(profile); + } + + public virtual IQueryable GetImportProfiles(bool? enabled = null) + { + var query = _importProfileRepository.Table + .Expand(x => x.ScheduleTask); + + if (enabled.HasValue) + { + query = query.Where(x => x.Enabled == enabled.Value); + } + + query = query.OrderBy(x => x.Name); + + return query; + } + + public virtual ImportProfile GetImportProfileById(int id) + { + if (id == 0) + return null; + + var profile = _importProfileRepository.Table + .Expand(x => x.ScheduleTask) + .FirstOrDefault(x => x.Id == id); + + return profile; + } + } +} diff --git a/src/Libraries/SmartStore.Services/Security/StandardPermissionProvider.cs b/src/Libraries/SmartStore.Services/Security/StandardPermissionProvider.cs index 886196b240..4f1032077a 100644 --- a/src/Libraries/SmartStore.Services/Security/StandardPermissionProvider.cs +++ b/src/Libraries/SmartStore.Services/Security/StandardPermissionProvider.cs @@ -50,6 +50,7 @@ public partial class StandardPermissionProvider : IPermissionProvider public static readonly PermissionRecord UploadPictures = new PermissionRecord { Name = "Admin area. Upload Pictures", SystemName = "UploadPictures", Category = "Configuration" }; public static readonly PermissionRecord ManageScheduleTasks = new PermissionRecord { Name = "Admin area. Manage Schedule Tasks", SystemName = "ManageScheduleTasks", Category = "Configuration" }; public static readonly PermissionRecord ManageExports = new PermissionRecord { Name = "Admin area. Manage Exports", SystemName = "ManageExports", Category = "Configuration" }; + public static readonly PermissionRecord ManageImports = new PermissionRecord { Name = "Admin area. Manage Imports", SystemName = "ManageImports", Category = "Configuration" }; public static readonly PermissionRecord ManageUrlRecords = new PermissionRecord { Name = "Admin area. Manage Url Records", SystemName = "ManageUrlRecords", Category = "Configuration" }; //public store permissions @@ -105,6 +106,7 @@ public virtual IEnumerable GetPermissions() UploadPictures, ManageScheduleTasks, ManageExports, + ManageImports, ManageUrlRecords, DisplayPrices, EnableShoppingCart, @@ -164,6 +166,7 @@ public virtual IEnumerable GetDefaultPermissions() UploadPictures, ManageScheduleTasks, ManageExports, + ManageImports, ManageUrlRecords, DisplayPrices, EnableShoppingCart, diff --git a/src/Libraries/SmartStore.Services/SmartStore.Services.csproj b/src/Libraries/SmartStore.Services/SmartStore.Services.csproj index b1c9cc5a3f..c61ee698c3 100644 --- a/src/Libraries/SmartStore.Services/SmartStore.Services.csproj +++ b/src/Libraries/SmartStore.Services/SmartStore.Services.csproj @@ -184,8 +184,12 @@ + + + + diff --git a/src/Presentation/SmartStore.Web.Framework/DependencyRegistrar.cs b/src/Presentation/SmartStore.Web.Framework/DependencyRegistrar.cs index eb2f5b2b1e..9536d25375 100644 --- a/src/Presentation/SmartStore.Web.Framework/DependencyRegistrar.cs +++ b/src/Presentation/SmartStore.Web.Framework/DependencyRegistrar.cs @@ -247,6 +247,7 @@ protected override void Load(ContainerBuilder builder) builder.RegisterType().As().InstancePerRequest(); builder.RegisterType().As().InstancePerRequest(); + builder.RegisterType().As().InstancePerRequest(); builder.RegisterType().As().InstancePerRequest(); builder.RegisterType().As().InstancePerRequest(); diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs new file mode 100644 index 0000000000..2c5040e624 --- /dev/null +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs @@ -0,0 +1,218 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Web.Mvc; +using SmartStore.Admin.Extensions; +using SmartStore.Admin.Models.DataExchange; +using SmartStore.Core.Domain; +using SmartStore.Core.IO; +using SmartStore.Services; +using SmartStore.Services.DataExchange.Import; +using SmartStore.Services.Helpers; +using SmartStore.Services.Security; +using SmartStore.Services.Tasks; +using SmartStore.Web.Framework.Controllers; +using SmartStore.Web.Framework.Filters; +using SmartStore.Web.Framework.Security; + +namespace SmartStore.Admin.Controllers +{ + [AdminAuthorize] + public class ImportController : AdminControllerBase + { + private readonly ICommonServices _services; + private readonly IImportProfileService _importService; + private readonly IDateTimeHelper _dateTimeHelper; + private readonly ITaskScheduler _taskScheduler; + + public ImportController( + ICommonServices services, + IImportProfileService importService, + IDateTimeHelper dateTimeHelper, + ITaskScheduler taskScheduler) + { + _services = services; + _importService = importService; + _dateTimeHelper = dateTimeHelper; + _taskScheduler = taskScheduler; + } + + #region Utilities + + private void PrepareProfileModel(ImportProfileModel model, ImportProfile profile, bool forEdit) + { + model.Id = profile.Id; + model.Name = profile.Name; + model.FolderName = profile.FolderName; + model.FileNames = profile.GetImportFiles(); + model.EntityType = profile.EntityType; + model.Enabled = profile.Enabled; + model.Skip = profile.Skip; + model.Take = profile.Take; + model.Cleanup = profile.Cleanup; + model.ScheduleTaskId = profile.SchedulingTaskId; + model.ScheduleTaskName = profile.ScheduleTask.Name.NaIfEmpty(); + model.IsTaskRunning = profile.ScheduleTask.IsRunning; + model.IsTaskEnabled = profile.ScheduleTask.Enabled; + model.LogFileExists = System.IO.File.Exists(profile.GetImportLogPath()); + } + + #endregion + + public ActionResult Index() + { + return RedirectToAction("List"); + } + + public ActionResult List() + { + if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageImports)) + return AccessDeniedView(); + + var profiles = _importService.GetImportProfiles().ToList(); + var model = new List(); + + foreach (var profile in profiles) + { + var profileModel = new ImportProfileModel(); + + PrepareProfileModel(profileModel, profile, false); + + profileModel.TaskModel = profile.ScheduleTask.ToScheduleTaskModel(_services.Localization, _dateTimeHelper, Url); + + model.Add(profileModel); + } + + return View(model); + } + + public ActionResult Edit(int id) + { + if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageImports)) + return AccessDeniedView(); + + var profile = _importService.GetImportProfileById(id); + if (profile == null) + return RedirectToAction("List"); + + var model = new ImportProfileModel(); + + PrepareProfileModel(model, profile, true); + + return View(model); + } + + [HttpPost, ParameterBasedOnFormName("save-continue", "continueEditing")] + [FormValueRequired("save", "save-continue")] + public ActionResult Edit(ImportProfileModel model, bool continueEditing) + { + if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageImports)) + return AccessDeniedView(); + + var profile = _importService.GetImportProfileById(model.Id); + if (profile == null) + return RedirectToAction("List"); + + if (!ModelState.IsValid) + { + PrepareProfileModel(model, profile, true); + return View(model); + } + + profile.Name = model.Name; + profile.FolderName = model.FolderName; + profile.Enabled = model.Enabled; + + + _importService.UpdateImportProfile(profile); + + NotifySuccess(T("Admin.Common.DataSuccessfullySaved")); + + return (continueEditing ? RedirectToAction("Edit", new { id = profile.Id }) : RedirectToAction("List")); + } + + [HttpPost, ActionName("Delete")] + public ActionResult DeleteConfirmed(int id) + { + if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageImports)) + return AccessDeniedView(); + + var profile = _importService.GetImportProfileById(id); + if (profile == null) + return RedirectToAction("List"); + + try + { + _importService.DeleteImportProfile(profile); + + NotifySuccess(T("Admin.Common.TaskSuccessfullyProcessed")); + + return RedirectToAction("List"); + } + catch (Exception exception) + { + NotifyError(exception); + } + + return RedirectToAction("Edit", new { id = profile.Id }); + } + + [HttpPost] + public ActionResult Execute(int id) + { + if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageImports)) + return AccessDeniedView(); + + var profile = _importService.GetImportProfileById(id); + if (profile == null) + return RedirectToAction("List"); + + _taskScheduler.RunSingleTask(profile.SchedulingTaskId, null); + + NotifyInfo(T("Admin.System.ScheduleTasks.RunNow.Progress")); + + return RedirectToAction("List"); + } + + public ActionResult DownloadLogFile(int id) + { + if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageImports)) + return AccessDeniedView(); + + var profile = _importService.GetImportProfileById(id); + if (profile == null) + return RedirectToAction("List"); + + var path = profile.GetImportLogPath(); + var stream = new FileStream(path, FileMode.Open); + + var result = new FileStreamResult(stream, "text/plain; charset=utf-8"); + result.FileDownloadName = profile.Name.ToValidFileName() + "-log.txt"; + + return result; + } + + public ActionResult DownloadExportFile(int id, string name) + { + if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageImports)) + return AccessDeniedView(); + + var profile = _importService.GetImportProfileById(id); + if (profile == null) + return RedirectToAction("List"); + + var path = Path.Combine(profile.GetImportFolder(true), name); + + if (!System.IO.File.Exists(path)) + path = Path.Combine(profile.GetImportFolder(false), name); + + var stream = new FileStream(path, FileMode.Open); + + var result = new FileStreamResult(stream, MimeTypes.MapNameToMimeType(path)); + result.FileDownloadName = Path.GetFileName(path); + + return result; + } + } +} \ No newline at end of file diff --git a/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ExportProfileModel.cs b/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ExportProfileModel.cs index 9c01bef987..73c26d57d2 100644 --- a/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ExportProfileModel.cs +++ b/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ExportProfileModel.cs @@ -49,14 +49,10 @@ public partial class ExportProfileModel : EntityModelBase public bool IsTaskRunning { get; set; } public bool IsTaskEnabled { get; set; } - [SmartResourceDisplayName("Admin.DataExchange.Export.LastExecution")] - [AllowHtml] - public string LastExecution { get; set; } - - [SmartResourceDisplayName("Admin.DataExchange.Export.Offset")] + [SmartResourceDisplayName("Admin.Common.RecordsSkip")] public int Offset { get; set; } - [SmartResourceDisplayName("Admin.DataExchange.Export.Limit")] + [SmartResourceDisplayName("Admin.Common.RecordsTake")] public int Limit { get; set; } [SmartResourceDisplayName("Admin.DataExchange.Export.BatchSize")] diff --git a/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ImportProfileModel.cs b/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ImportProfileModel.cs new file mode 100644 index 0000000000..a1a663f693 --- /dev/null +++ b/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ImportProfileModel.cs @@ -0,0 +1,46 @@ +using System.Collections.Generic; +using FluentValidation.Attributes; +using SmartStore.Admin.Models.Tasks; +using SmartStore.Admin.Validators.DataExchange; +using SmartStore.Web.Framework; +using SmartStore.Web.Framework.Modelling; + +namespace SmartStore.Admin.Models.DataExchange +{ + [Validator(typeof(ImportProfileValidator))] + public partial class ImportProfileModel : EntityModelBase + { + [SmartResourceDisplayName("Admin.DataExchange.Import.Name")] + public string Name { get; set; } + + [SmartResourceDisplayName("Admin.DataExchange.Import.FolderName")] + public string FolderName { get; set; } + + [SmartResourceDisplayName("Common.Files")] + public List FileNames { get; set; } + + [SmartResourceDisplayName("Admin.Common.Entity")] + public string EntityType { get; set; } + + [SmartResourceDisplayName("Common.Enabled")] + public bool Enabled { get; set; } + + [SmartResourceDisplayName("Admin.Common.RecordsSkip")] + public int Skip { get; set; } + + [SmartResourceDisplayName("Admin.Common.RecordsTake")] + public int Take { get; set; } + + [SmartResourceDisplayName("Admin.DataExchange.Import.Cleanup")] + public bool Cleanup { get; set; } + + [SmartResourceDisplayName("Common.Execution")] + public int ScheduleTaskId { get; set; } + public string ScheduleTaskName { get; set; } + public bool IsTaskRunning { get; set; } + public bool IsTaskEnabled { get; set; } + + public ScheduleTaskModel TaskModel { get; set; } + public bool LogFileExists { get; set; } + } +} \ No newline at end of file diff --git a/src/Presentation/SmartStore.Web/Administration/SmartStore.Admin.csproj b/src/Presentation/SmartStore.Web/Administration/SmartStore.Admin.csproj index 8beba42ebc..7bc7cfc138 100644 --- a/src/Presentation/SmartStore.Web/Administration/SmartStore.Admin.csproj +++ b/src/Presentation/SmartStore.Web/Administration/SmartStore.Admin.csproj @@ -181,6 +181,7 @@ + @@ -252,6 +253,7 @@ + @@ -374,6 +376,7 @@ + @@ -533,6 +536,7 @@ + diff --git a/src/Presentation/SmartStore.Web/Administration/Validators/DataExchange/ImportProfileValidator.cs b/src/Presentation/SmartStore.Web/Administration/Validators/DataExchange/ImportProfileValidator.cs new file mode 100644 index 0000000000..3760f5bae1 --- /dev/null +++ b/src/Presentation/SmartStore.Web/Administration/Validators/DataExchange/ImportProfileValidator.cs @@ -0,0 +1,22 @@ +using System.IO; +using System.Linq; +using FluentValidation; +using SmartStore.Admin.Models.DataExchange; +using SmartStore.Services.Localization; + +namespace SmartStore.Admin.Validators.DataExchange +{ + public partial class ImportProfileValidator : AbstractValidator + { + public ImportProfileValidator(ILocalizationService localization) + { + RuleFor(x => x.Name) + .NotEmpty() + .WithMessage(localization.GetResource("Admin.Validation.Name")); + + RuleFor(x => x.FolderName) + .Must(x => x.HasValue() && !x.IsCaseInsensitiveEqual("con") && !Path.GetInvalidFileNameChars().Any(y => x.Contains(y))) + .WithMessage(localization.GetResource("Admin.DataExchange.Import.FolderName.Validate")); + } + } +} \ No newline at end of file diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Export/List.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Export/List.cshtml index 9ddcf27347..9405ee9369 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Export/List.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Export/List.cshtml @@ -157,7 +157,7 @@ else url: dialog.attr('data-urldelete'), ask: dialog.find('.modal-ask-delete').text(), callbackSuccess: function (resp) { - refreshGrid(forExport); + refreshGrid(); } }); return false; diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Import/List.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Import/List.cshtml new file mode 100644 index 0000000000..105b8b85b4 --- /dev/null +++ b/src/Presentation/SmartStore.Web/Administration/Views/Import/List.cshtml @@ -0,0 +1,167 @@ +@using SmartStore.Core.Domain.DataExchange; +@using SmartStore.Admin.Models.DataExchange; +@using Telerik.Web.Mvc.UI; +@model List +@{ + ViewBag.Title = T("Common.Import").Text; +} + +
+
+ + @T("Common.Import") +
+ +
+ +
+ + + +@if(Model.Count > 0) +{ +
@Html.SmartLabelFor(model => model.Id) - @Model.Id.ToString() + @Html.DisplayFor(model => model.Id) @Html.ValidationMessageFor(model => model.Id)
+ + + + + + + + + + + + + @foreach (var profile in Model) + { + + + + + + + + + + } + +
@T("Admin.DataExchange.Import.Name")@T("Common.Enabled")@T("Admin.Common.Entity")@T("Common.Files")@T("Admin.System.ScheduleTasks.LastStart")@T("Admin.System.ScheduleTasks.NextRun")@T("Admin.Common.Actions")
+ @profile.Name + + @Html.SymbolForBool(profile.Enabled) + + @profile.EntityType.NaIfEmpty() + + @(string.Join("
", profile.FileNames)) +
+
+ @Html.Partial("~/Administration/Views/ScheduleTask/_LastRun.cshtml", profile.TaskModel) +
+
+
+ @Html.Partial("~/Administration/Views/ScheduleTask/_NextRun.cshtml", profile.TaskModel) +
+
+
+ + + + @T("Common.Cancel") + + + +  @T("Admin.Configuration.ActivityLog") + +
+} +else +{ +
+ + @T("Admin.DataExchange.Import.NoProfiles") +
+} + + diff --git a/src/Presentation/SmartStore.Web/Administration/sitemap.config b/src/Presentation/SmartStore.Web/Administration/sitemap.config index 573d1227b0..ac42790f6b 100644 --- a/src/Presentation/SmartStore.Web/Administration/sitemap.config +++ b/src/Presentation/SmartStore.Web/Administration/sitemap.config @@ -127,6 +127,7 @@ + From f31826e68d80543cc9dd3535843a118f9e7c3a86 Mon Sep 17 00:00:00 2001 From: Murat Cakir Date: Wed, 9 Dec 2015 18:08:48 +0100 Subject: [PATCH 071/626] Fixes #831: Message Template list page crashes --- .../Administration/Controllers/MessageTemplateController.cs | 1 + .../Administration/Models/Messages/MessageTemplateModel.cs | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/MessageTemplateController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/MessageTemplateController.cs index 699dbcd4f6..be6c73a92b 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/MessageTemplateController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/MessageTemplateController.cs @@ -171,6 +171,7 @@ public ActionResult List(GridCommand command, MessageTemplateListModel model) Data = messageTemplates.Select(x => x.ToModel()), Total = messageTemplates.Count }; + return new JsonResult { Data = gridModel diff --git a/src/Presentation/SmartStore.Web/Administration/Models/Messages/MessageTemplateModel.cs b/src/Presentation/SmartStore.Web/Administration/Models/Messages/MessageTemplateModel.cs index 4367223014..9dab2a81ba 100644 --- a/src/Presentation/SmartStore.Web/Administration/Models/Messages/MessageTemplateModel.cs +++ b/src/Presentation/SmartStore.Web/Administration/Models/Messages/MessageTemplateModel.cs @@ -2,6 +2,7 @@ using System.Web.Mvc; using System.Web.Script.Serialization; using FluentValidation.Attributes; +using Newtonsoft.Json; using SmartStore.Admin.Models.Stores; using SmartStore.Admin.Validators.Messages; using SmartStore.Collections; @@ -23,7 +24,7 @@ public MessageTemplateModel() } [SmartResourceDisplayName("Admin.ContentManagement.MessageTemplates.Fields.AllowedTokens")] - [ScriptIgnore] + [ScriptIgnore, JsonIgnore] public TreeNode TokensTree { get; set; } [SmartResourceDisplayName("Admin.ContentManagement.MessageTemplates.Fields.Name")] From e2b6680bae0c9293afc3cee2d0841ff49433cc6e Mon Sep 17 00:00:00 2001 From: Murat Cakir Date: Wed, 9 Dec 2015 20:01:03 +0100 Subject: [PATCH 072/626] Updated ua-parser (UserAgent parser) to latest version. Also updated custom mobile & bot definitions. Plus: regex file is loaded from disk now (App_Data/ua-parser.regexes.yaml) --- .../SmartStore.Services/Common/IUserAgent.cs | 18 + .../Common/UAParserUserAgent.cs | 23 +- .../SmartStore.Services.csproj | 5 +- .../SmartStore.Services/packages.config | 2 +- .../App_Data/ua-parser.regexes.yaml | 4767 +++++++++++++++++ 5 files changed, 4806 insertions(+), 9 deletions(-) create mode 100644 src/Presentation/SmartStore.Web/App_Data/ua-parser.regexes.yaml diff --git a/src/Libraries/SmartStore.Services/Common/IUserAgent.cs b/src/Libraries/SmartStore.Services/Common/IUserAgent.cs index c6530bda07..a232323b07 100644 --- a/src/Libraries/SmartStore.Services/Common/IUserAgent.cs +++ b/src/Libraries/SmartStore.Services/Common/IUserAgent.cs @@ -67,6 +67,13 @@ private static string FormatVersionString(params string[] parts) public sealed class UserAgentInfo { + private static readonly HashSet s_Bots = new HashSet(StringComparer.InvariantCultureIgnoreCase) + { + "BingPreview" + }; + + private bool? _isBot; + public UserAgentInfo(string family, string major, string minor, string patch) { this.Family = family; @@ -83,6 +90,17 @@ public override string ToString() public string Major { get; private set; } public string Minor { get; private set; } public string Patch { get; private set; } + public bool IsBot + { + get + { + if (!_isBot.HasValue) + { + _isBot = s_Bots.Contains(Family); + } + return _isBot.Value; + } + } } internal static class VersionString diff --git a/src/Libraries/SmartStore.Services/Common/UAParserUserAgent.cs b/src/Libraries/SmartStore.Services/Common/UAParserUserAgent.cs index f0726c906c..060c127d3f 100644 --- a/src/Libraries/SmartStore.Services/Common/UAParserUserAgent.cs +++ b/src/Libraries/SmartStore.Services/Common/UAParserUserAgent.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Text.RegularExpressions; using System.Web; +using SmartStore.Utilities; using uap = UAParser; namespace SmartStore.Services.Common @@ -14,7 +15,7 @@ public class UAParserUserAgent : IUserAgent # region Mobile UAs, OS & Devices - private static readonly HashSet s_MobileOS = new HashSet + private static readonly HashSet s_MobileOS = new HashSet(StringComparer.InvariantCultureIgnoreCase) { "Android", "iOS", @@ -32,8 +33,10 @@ public class UAParserUserAgent : IUserAgent "Maemo" }; - private static readonly HashSet s_MobileBrowsers = new HashSet + private static readonly HashSet s_MobileBrowsers = new HashSet(StringComparer.InvariantCultureIgnoreCase) { + "Googlebot-Mobile", + "Baiduspider-mobile", "Android", "Firefox Mobile", "Opera Mobile", @@ -80,7 +83,7 @@ public class UAParserUserAgent : IUserAgent "Skyfire" }; - private static readonly HashSet s_MobileDevices = new HashSet + private static readonly HashSet s_MobileDevices = new HashSet(StringComparer.InvariantCultureIgnoreCase) { "BlackBerry", "MI PAD", @@ -116,7 +119,8 @@ public class UAParserUserAgent : IUserAgent static UAParserUserAgent() { - s_uap = uap.Parser.GetDefault(); + //s_uap = uap.Parser.GetDefault(); + s_uap = uap.Parser.FromYamlFile(CommonHelper.MapPath("~/App_Data/ua-parser.regexes.yaml")); } public UAParserUserAgent(HttpContextBase httpContext) @@ -176,7 +180,7 @@ public virtual DeviceInfo Device if (_device == null) { var tmp = s_uap.ParseDevice(this.RawValue); - _device = new DeviceInfo(tmp.Family, tmp.IsSpider); + _device = new DeviceInfo(tmp.Family, tmp.IsSpider()); } return _device; } @@ -201,7 +205,7 @@ public virtual bool IsBot { if (!_isBot.HasValue) { - _isBot = _httpContext.Request.Browser.Crawler || this.Device.IsBot; + _isBot = _httpContext.Request.Browser.Crawler || this.Device.IsBot || this.UserAgent.IsBot; } return _isBot.Value; } @@ -247,7 +251,14 @@ public virtual bool IsPdfConverter return _isPdfConverter.Value; } } + } + internal static class DeviceExtensions + { + internal static bool IsSpider(this UAParser.Device device) + { + return device.Family.Equals("Spider", StringComparison.InvariantCultureIgnoreCase); + } } } diff --git a/src/Libraries/SmartStore.Services/SmartStore.Services.csproj b/src/Libraries/SmartStore.Services/SmartStore.Services.csproj index b1c9cc5a3f..9276e94dc0 100644 --- a/src/Libraries/SmartStore.Services/SmartStore.Services.csproj +++ b/src/Libraries/SmartStore.Services/SmartStore.Services.csproj @@ -154,8 +154,9 @@ - - ..\..\packages\UAParser.1.2.0.0\lib\net35-Client\UAParser.dll + + ..\..\packages\UAParser.2.0.0.0\lib\net40-Client\UAParser.dll + True diff --git a/src/Libraries/SmartStore.Services/packages.config b/src/Libraries/SmartStore.Services/packages.config index 23354a2a94..7f5b29df78 100644 --- a/src/Libraries/SmartStore.Services/packages.config +++ b/src/Libraries/SmartStore.Services/packages.config @@ -16,5 +16,5 @@ - + \ No newline at end of file diff --git a/src/Presentation/SmartStore.Web/App_Data/ua-parser.regexes.yaml b/src/Presentation/SmartStore.Web/App_Data/ua-parser.regexes.yaml new file mode 100644 index 0000000000..6ef74a0d89 --- /dev/null +++ b/src/Presentation/SmartStore.Web/App_Data/ua-parser.regexes.yaml @@ -0,0 +1,4767 @@ +user_agent_parsers: + #### SPECIAL CASES TOP #### + + # @note: iOS / OSX Applications + - regex: '(CFNetwork)(?:/(\d+)\.(\d+)\.?(\d+)?)?' + family_replacement: 'CFNetwork' + + # Pingdom + - regex: '(Pingdom.com_bot_version_)(\d+)\.(\d+)' + family_replacement: 'PingdomBot' + + # Facebook + - regex: '(facebookexternalhit)/(\d+)\.(\d+)' + family_replacement: 'FacebookBot' + + # Google Plus + - regex: 'Google.*/\+/web/snippet' + family_replacement: 'GooglePlusBot' + + # Bots Pattern '/name-0.0' + - regex: '/((?:Ant-)?Nutch|[A-z]+[Bb]ot|[A-z]+[Ss]pider|Axtaris|fetchurl|Isara|ShopSalad|Tailsweep)[ \-](\d+)(?:\.(\d+)(?:\.(\d+))?)?' + # Bots Pattern 'name/0.0' + - regex: '(008|Altresium|Argus|BaiduMobaider|BoardReader|DNSGroup|DataparkSearch|EDI|Goodzer|Grub|INGRID|Infohelfer|LinkedInBot|LOOQ|Nutch|PathDefender|Peew|PostPost|Steeler|Twitterbot|VSE|WebCrunch|WebZIP|Y!J-BR[A-Z]|YahooSeeker|envolk|sproose|wminer)/(\d+)(?:\.(\d+)(?:\.(\d+))?)?' + + # MSIECrawler + - regex: '(MSIE) (\d+)\.(\d+)([a-z]\d?)?;.* MSIECrawler' + family_replacement: 'MSIECrawler' + + # Downloader ... + - regex: '(Google-HTTP-Java-Client|Apache-HttpClient|http%20client|Python-urllib|HttpMonitor|TLSProber|WinHTTP|JNLP)(?:[ /](\d+)(?:\.(\d+)(?:\.(\d+))?)?)?' + + # Bots + - regex: '(1470\.net crawler|50\.nu|8bo Crawler Bot|Aboundex|Accoona-[A-z]+-Agent|AdsBot-Google(?:-[a-z]+)?|altavista|AppEngine-Google|archive.*?\.org_bot|archiver|Ask Jeeves|[Bb]ai[Dd]u[Ss]pider(?:-[A-Za-z]+)*|bingbot|BingPreview|blitzbot|BlogBridge|BoardReader(?: [A-Za-z]+)*|boitho.com-dc|BotSeer|\b\w*favicon\w*\b|\bYeti(?:-[a-z]+)?|Catchpoint bot|[Cc]harlotte|Checklinks|clumboot|Comodo HTTP\(S\) Crawler|Comodo-Webinspector-Crawler|ConveraCrawler|CRAWL-E|CrawlConvera|Daumoa(?:-feedfetcher)?|Feed Seeker Bot|findlinks|Flamingo_SearchEngine|FollowSite Bot|furlbot|Genieo|gigabot|GomezAgent|gonzo1|(?:[a-zA-Z]+-)?Googlebot(?:-[a-zA-Z]+)?|Google SketchUp|grub-client|gsa-crawler|heritrix|HiddenMarket|holmes|HooWWWer|htdig|ia_archiver|ICC-Crawler|Icarus6j|ichiro(?:/mobile)?|IconSurf|IlTrovatore(?:-Setaccio)?|InfuzApp|Innovazion Crawler|InternetArchive|IP2[a-z]+Bot|jbot\b|KaloogaBot|Kraken|Kurzor|larbin|LEIA|LesnikBot|Linguee Bot|LinkAider|LinkedInBot|Lite Bot|Llaut|lycos|Mail\.RU_Bot|masidani_bot|Mediapartners-Google|Microsoft .*? Bot|mogimogi|mozDex|MJ12bot|msnbot(?:-media *)?|msrbot|netresearch|Netvibes|NewsGator[^/]*|^NING|Nutch[^/]*|Nymesis|ObjectsSearch|Orbiter|OOZBOT|PagePeeker|PagesInventory|PaxleFramework|Peeplo Screenshot Bot|PlantyNet_WebRobot|Pompos|Read%20Later|Reaper|RedCarpet|Retreiver|Riddler|Rival IQ|scooter|Scrapy|Scrubby|searchsight|seekbot|semanticdiscovery|Simpy|SimplePie|SEOstats|SimpleRSS|SiteCon|Slurp|snappy|Speedy Spider|Squrl Java|TheUsefulbot|ThumbShotsBot|Thumbshots\.ru|TwitterBot|URL2PNG|Vagabondo|VoilaBot|^vortex|Votay bot|^voyager|WASALive.Bot|Web-sniffer|WebThumb|WeSEE:[A-z]+|WhatWeb|WIRE|WordPress|Wotbox|www\.almaden\.ibm\.com|Xenu(?:.s)? Link Sleuth|Xerka [A-z]+Bot|yacy(?:bot)?|Yahoo[a-z]*Seeker|Yahoo! Slurp|Yandex\w+|YodaoBot(?:-[A-z]+)?|YottaaMonitor|Yowedo|^Zao|^Zao-Crawler|ZeBot_www\.ze\.bz|ZooShot|ZyBorg)(?:[ /]v?(\d+)(?:\.(\d+)(?:\.(\d+))?)?)?' + + # Bots General matcher 'name/0.0' + - regex: '(?:\/[A-Za-z0-9\.]+)? *([A-Za-z0-9 \-_\!\[\]:]*(?:[Aa]rchiver|[Ii]ndexer|[Ss]craper|[Bb]ot|[Ss]pider|[Cc]rawl[a-z]*))/(\d+)(?:\.(\d+)(?:\.(\d+))?)?' + # Bots General matcher 'name 0.0' + - regex: '(?:\/[A-Za-z0-9\.]+)? *([A-Za-z0-9 _\!\[\]:]*(?:[Aa]rchiver|[Ii]ndexer|[Ss]craper|[Bb]ot|[Ss]pider|[Cc]rawl[a-z]*)) (\d+)(?:\.(\d+)(?:\.(\d+))?)?' + # Bots containing spider|scrape|bot(but not CUBOT)|Crawl + - regex: '((?:[A-z0-9]+|[A-z\-]+ ?)?(?: the )?(?:[Ss][Pp][Ii][Dd][Ee][Rr]|[Ss]crape|[A-Za-z0-9-]*(?:[^C][^Uu])[Bb]ot|[Cc][Rr][Aa][Ww][Ll])[A-z0-9]*)(?:(?:[ /]| v)(\d+)(?:\.(\d+)(?:\.(\d+))?)?)?' + + # HbbTV standard defines what features the browser should understand. + # but it's like targeting "HTML5 browsers", effective browser support depends on the model + # See os_parsers if you want to target a specific TV + - regex: '(HbbTV)/(\d+)\.(\d+)\.(\d+) \(' + + # must go before Firefox to catch Chimera/SeaMonkey/Camino + - regex: '(Chimera|SeaMonkey|Camino)/(\d+)\.(\d+)\.?([ab]?\d+[a-z]*)?' + + # Social Networks + # Facebook + - regex: '\[FB.*;(FBAV)/(\d+)(?:\.(\d+)(?:\.(\d)+)?)?' + family_replacement: 'Facebook' + # Pinterest + - regex: '\[(Pinterest)/[^\]]+\]' + - regex: '(Pinterest)(?: for Android(?: Tablet)?)?/(\d+)(?:\.(\d+)(?:\.(\d)+)?)?' + + # Firefox + - regex: '(Pale[Mm]oon)/(\d+)\.(\d+)\.?(\d+)?' + family_replacement: 'Pale Moon (Firefox Variant)' + - regex: '(Fennec)/(\d+)\.(\d+)\.?([ab]?\d+[a-z]*)' + family_replacement: 'Firefox Mobile' + - regex: '(Fennec)/(\d+)\.(\d+)(pre)' + family_replacement: 'Firefox Mobile' + - regex: '(Fennec)/(\d+)\.(\d+)' + family_replacement: 'Firefox Mobile' + - regex: '(?:Mobile|Tablet);.*(Firefox)/(\d+)\.(\d+)' + family_replacement: 'Firefox Mobile' + - regex: '(Namoroka|Shiretoko|Minefield)/(\d+)\.(\d+)\.(\d+(?:pre)?)' + family_replacement: 'Firefox ($1)' + - regex: '(Firefox)/(\d+)\.(\d+)(a\d+[a-z]*)' + family_replacement: 'Firefox Alpha' + - regex: '(Firefox)/(\d+)\.(\d+)(b\d+[a-z]*)' + family_replacement: 'Firefox Beta' + - regex: '(Firefox)-(?:\d+\.\d+)?/(\d+)\.(\d+)(a\d+[a-z]*)' + family_replacement: 'Firefox Alpha' + - regex: '(Firefox)-(?:\d+\.\d+)?/(\d+)\.(\d+)(b\d+[a-z]*)' + family_replacement: 'Firefox Beta' + - regex: '(Namoroka|Shiretoko|Minefield)/(\d+)\.(\d+)([ab]\d+[a-z]*)?' + family_replacement: 'Firefox ($1)' + - regex: '(Firefox).*Tablet browser (\d+)\.(\d+)\.(\d+)' + family_replacement: 'MicroB' + - regex: '(MozillaDeveloperPreview)/(\d+)\.(\d+)([ab]\d+[a-z]*)?' + - regex: '(FxiOS)/(\d+)\.(\d+)(\.(\d+))?(\.(\d+))?' + family_replacement: 'Firefox iOS' + + # e.g.: Flock/2.0b2 + - regex: '(Flock)/(\d+)\.(\d+)(b\d+?)' + + # RockMelt + - regex: '(RockMelt)/(\d+)\.(\d+)\.(\d+)' + + # e.g.: Fennec/0.9pre + - regex: '(Navigator)/(\d+)\.(\d+)\.(\d+)' + family_replacement: 'Netscape' + + - regex: '(Navigator)/(\d+)\.(\d+)([ab]\d+)' + family_replacement: 'Netscape' + + - regex: '(Netscape6)/(\d+)\.(\d+)\.?([ab]?\d+)?' + family_replacement: 'Netscape' + + - regex: '(MyIBrow)/(\d+)\.(\d+)' + family_replacement: 'My Internet Browser' + + # Opera will stop at 9.80 and hide the real version in the Version string. + # see: http://dev.opera.com/articles/view/opera-ua-string-changes/ + - regex: '(Opera Tablet).*Version/(\d+)\.(\d+)(?:\.(\d+))?' + - regex: '(Opera Mini)(?:/att)?/(\d+)?(?:\.(\d+))?(?:\.(\d+))?' + - regex: '(Opera)/.+Opera Mobi.+Version/(\d+)\.(\d+)' + family_replacement: 'Opera Mobile' + - regex: '(Opera)/(\d+)\.(\d+).+Opera Mobi' + family_replacement: 'Opera Mobile' + - regex: 'Opera Mobi.+(Opera)(?:/|\s+)(\d+)\.(\d+)' + family_replacement: 'Opera Mobile' + - regex: 'Opera Mobi' + family_replacement: 'Opera Mobile' + - regex: '(Opera)/9.80.*Version/(\d+)\.(\d+)(?:\.(\d+))?' + + # Opera 14 for Android uses a WebKit render engine. + - regex: '(?:Mobile Safari).*(OPR)/(\d+)\.(\d+)\.(\d+)' + family_replacement: 'Opera Mobile' + + # Opera >=15 for Desktop is similar to Chrome but includes an "OPR" Version string. + - regex: '(?:Chrome).*(OPR)/(\d+)\.(\d+)\.(\d+)' + family_replacement: 'Opera' + + # Opera Coast + - regex: '(Coast)/(\d+).(\d+).(\d+)' + family_replacement: 'Opera Coast' + + # Opera Mini for iOS (from version 8.0.0) + - regex: '(OPiOS)/(\d+).(\d+).(\d+)' + family_replacement: 'Opera Mini' + + # Palm WebOS looks a lot like Safari. + - regex: '(hpw|web)OS/(\d+)\.(\d+)(?:\.(\d+))?' + family_replacement: 'webOS Browser' + + # LuaKit has no version info. + # http://luakit.org/projects/luakit/ + - regex: '(luakit)' + family_replacement: 'LuaKit' + + # Snowshoe + - regex: '(Snowshoe)/(\d+)\.(\d+).(\d+)' + + # Lightning (for Thunderbird) + # http://www.mozilla.org/projects/calendar/lightning/ + - regex: '(Lightning)/(\d+)\.(\d+)\.?((?:[ab]?\d+[a-z]*)|(?:\d*))' + + # Swiftfox + - regex: '(Firefox)/(\d+)\.(\d+)\.(\d+(?:pre)?) \(Swiftfox\)' + family_replacement: 'Swiftfox' + - regex: '(Firefox)/(\d+)\.(\d+)([ab]\d+[a-z]*)? \(Swiftfox\)' + family_replacement: 'Swiftfox' + + # Rekonq + - regex: '(rekonq)/(\d+)\.(\d+)\.?(\d+)? Safari' + family_replacement: 'Rekonq' + - regex: 'rekonq' + family_replacement: 'Rekonq' + + # Conkeror lowercase/uppercase + # http://conkeror.org/ + - regex: '(conkeror|Conkeror)/(\d+)\.(\d+)\.?(\d+)?' + family_replacement: 'Conkeror' + + # catches lower case konqueror + - regex: '(konqueror)/(\d+)\.(\d+)\.(\d+)' + family_replacement: 'Konqueror' + + - regex: '(WeTab)-Browser' + + - regex: '(Comodo_Dragon)/(\d+)\.(\d+)\.(\d+)' + family_replacement: 'Comodo Dragon' + + - regex: '(Symphony) (\d+).(\d+)' + + - regex: '(Minimo)' + + - regex: 'PLAYSTATION 3.+WebKit' + family_replacement: 'NetFront NX' + - regex: 'PLAYSTATION 3' + family_replacement: 'NetFront' + - regex: '(PlayStation Portable)' + family_replacement: 'NetFront' + - regex: '(PlayStation Vita)' + family_replacement: 'NetFront NX' + + - regex: 'AppleWebKit.+ (NX)/(\d+)\.(\d+)\.(\d+)' + family_replacement: 'NetFront NX' + - regex: '(Nintendo 3DS)' + family_replacement: 'NetFront NX' + + # Amazon Silk, should go before Safari and Chrome Mobile + - regex: '(Silk)/(\d+)\.(\d+)(?:\.([0-9\-]+))?' + family_replacement: 'Amazon Silk' + + + # @ref: http://www.puffinbrowser.com + - regex: '(Puffin)/(\d+)\.(\d+)(?:\.(\d+))?' + + # Edge Mobile + - regex: 'Windows Phone .*(Edge)/(\d+)\.(\d+)' + family_replacement: 'Edge Mobile' + + # Chrome Mobile + - regex: '(CrMo)/(\d+)\.(\d+)\.(\d+)\.(\d+)' + family_replacement: 'Chrome Mobile' + - regex: '(CriOS)/(\d+)\.(\d+)\.(\d+)\.(\d+)' + family_replacement: 'Chrome Mobile iOS' + - regex: '(Chrome)/(\d+)\.(\d+)\.(\d+)\.(\d+) Mobile' + family_replacement: 'Chrome Mobile' + + # Chrome Frame must come before MSIE. + - regex: '(chromeframe)/(\d+)\.(\d+)\.(\d+)' + family_replacement: 'Chrome Frame' + + # UC Browser + - regex: '(UCBrowser)[ /](\d+)\.(\d+)\.(\d+)' + family_replacement: 'UC Browser' + - regex: '(UC Browser)[ /](\d+)\.(\d+)\.(\d+)' + - regex: '(UC Browser|UCBrowser|UCWEB)(\d+)\.(\d+)\.(\d+)' + family_replacement: 'UC Browser' + + # Tizen Browser (second case included in browser/major.minor regex) + - regex: '(SLP Browser)/(\d+)\.(\d+)' + family_replacement: 'Tizen Browser' + + # Sogou Explorer 2.X + - regex: '(SE 2\.X) MetaSr (\d+)\.(\d+)' + family_replacement: 'Sogou Explorer' + + # Baidu Browsers (desktop spoofs chrome & IE, explorer is mobile) + - regex: '(baidubrowser)[/\s](\d+)' + family_replacement: 'Baidu Browser' + - regex: '(FlyFlow)/(\d+)\.(\d+)' + family_replacement: 'Baidu Explorer' + + # QQ Browsers + - regex: '(MQQBrowser/Mini)(?:(\d+)(?:\.(\d+)(?:\.(\d+))?)?)?' + family_replacement: 'QQ Browser Mini' + - regex: '(MQQBrowser)(?:/(\d+)(?:\.(\d+)(?:\.(\d+))?)?)?' + family_replacement: 'QQ Browser Mobile' + - regex: '(QQBrowser)(?:/(\d+)(?:\.(\d+)\.(\d+)(?:\.(\d+))?)?)?' + family_replacement: 'QQ Browser' + + # Rackspace Monitoring + - regex: '(Rackspace Monitoring)/(\d+)\.(\d+)' + family_replacement: 'RackspaceBot' + + # PyAMF + - regex: '(PyAMF)/(\d+)\.(\d+)\.(\d+)' + + # Yandex Browser + - regex: '(YaBrowser)/(\d+)\.(\d+)\.(\d+)' + family_replacement: 'Yandex Browser' + + # Mail.ru Amigo/Internet Browser (Chromium-based) + - regex: '(Chrome)/(\d+)\.(\d+)\.(\d+).* MRCHROME' + family_replacement: 'Mail.ru Chromium Browser' + + # AOL Browser (IE-based) + - regex: '(AOL) (\d+)\.(\d+); AOLBuild (\d+)' + + #### END SPECIAL CASES TOP #### + + #### MAIN CASES - this catches > 50% of all browsers #### + + # Browser/major_version.minor_version.beta_version + - regex: '(AdobeAIR|FireWeb|Jasmine|ANTGalio|Midori|Fresco|Lobo|PaleMoon|Maxthon|Lynx|OmniWeb|Dillo|Camino|Demeter|Fluid|Fennec|Epiphany|Shiira|Sunrise|Spotify|Flock|Netscape|Lunascape|WebPilot|NetFront|Netfront|Konqueror|SeaMonkey|Kazehakase|Vienna|Iceape|Iceweasel|IceWeasel|Iron|K-Meleon|Sleipnir|Galeon|GranParadiso|Opera Mini|iCab|NetNewsWire|ThunderBrowse|Iris|UP\.Browser|Bunjalloo|Google Earth|Raven for Mac|Openwave)/(\d+)\.(\d+)\.(\d+)' + + # Outlook 2007 + - regex: 'MSOffice 12' + family_replacement: 'Outlook' + v1_replacement: '2007' + + # Outlook 2010 + - regex: 'MSOffice 14' + family_replacement: 'Outlook' + v1_replacement: '2010' + + # Outlook 2013 + - regex: 'Microsoft Outlook 15\.\d+\.\d+' + family_replacement: 'Outlook' + v1_replacement: '2013' + + # Apple Air Mail + - regex: '(Airmail) (\d+)\.(\d+)(?:\.(\d+))?' + + # Thunderbird + - regex: '(Thunderbird)/(\d+)\.(\d+)\.(\d+(?:pre)?)' + family_replacement: 'Thunderbird' + + # Vivaldi uses "Vivaldi" + - regex: '(Vivaldi)/(\d+)\.(\d+)\.(\d+)' + + # Edge/major_version.minor_version + - regex: '(Edge)/(\d+)\.(\d+)' + + # Chrome/Chromium/major_version.minor_version.beta_version + - regex: '(Chromium|Chrome)/(\d+)\.(\d+)\.(\d+)' + + # Dolphin Browser + # @ref: http://www.dolphin.com + - regex: '\b(Dolphin)(?: |HDCN/|/INT\-)(\d+)\.(\d+)\.?(\d+)?' + + # Browser/major_version.minor_version + - regex: '(bingbot|Bolt|Jasmine|IceCat|Skyfire|Midori|Maxthon|Lynx|Arora|IBrowse|Dillo|Camino|Shiira|Fennec|Phoenix|Chrome|Flock|Netscape|Lunascape|Epiphany|WebPilot|Opera Mini|Opera|NetFront|Netfront|Konqueror|Googlebot|SeaMonkey|Kazehakase|Vienna|Iceape|Iceweasel|IceWeasel|Iron|K-Meleon|Sleipnir|Galeon|GranParadiso|iCab|iTunes|MacAppStore|NetNewsWire|Space Bison|Stainless|Orca|Dolfin|BOLT|Minimo|Tizen Browser|Polaris|Abrowser|Planetweb|ICE Browser|mDolphin|qutebrowser|Otter|QupZilla)/(\d+)\.(\d+)\.?(\d+)?' + + # Chrome/Chromium/major_version.minor_version + - regex: '(Chromium|Chrome)/(\d+)\.(\d+)' + + ########## + # IE Mobile needs to happen before Android to catch cases such as: + # Mozilla/5.0 (Mobile; Windows Phone 8.1; Android 4.0; ARM; Trident/7.0; Touch; rv:11.0; IEMobile/11.0; NOKIA; Lumia 920)... + # Mozilla/5.0 (Mobile; Windows Phone 8.1; Android 4.0; ARM; Trident/7.0; Touch; rv:11.0; IEMobile/11.0; NOKIA; Lumia 920; ANZ821)... + # Mozilla/5.0 (Mobile; Windows Phone 8.1; Android 4.0; ARM; Trident/7.0; Touch; rv:11.0; IEMobile/11.0; NOKIA; Lumia 920; Orange)... + # Mozilla/5.0 (Mobile; Windows Phone 8.1; Android 4.0; ARM; Trident/7.0; Touch; rv:11.0; IEMobile/11.0; NOKIA; Lumia 920; Vodafone)... + ########## + + # IE Mobile + - regex: '(IEMobile)[ /](\d+)\.(\d+)' + family_replacement: 'IE Mobile' + + # Browser major_version.minor_version.beta_version (space instead of slash) + - regex: '(iRider|Crazy Browser|SkipStone|iCab|Lunascape|Sleipnir|Maemo Browser) (\d+)\.(\d+)\.(\d+)' + # Browser major_version.minor_version (space instead of slash) + - regex: '(iCab|Lunascape|Opera|Android|Jasmine|Polaris) (\d+)\.(\d+)\.?(\d+)?' + + # Kindle WebKit + - regex: '(Kindle)/(\d+)\.(\d+)' + + # weird android UAs + - regex: '(Android) Donut' + v1_replacement: '1' + v2_replacement: '2' + + - regex: '(Android) Eclair' + v1_replacement: '2' + v2_replacement: '1' + + - regex: '(Android) Froyo' + v1_replacement: '2' + v2_replacement: '2' + + - regex: '(Android) Gingerbread' + v1_replacement: '2' + v2_replacement: '3' + + - regex: '(Android) Honeycomb' + v1_replacement: '3' + + # desktop mode + # http://www.anandtech.com/show/3982/windows-phone-7-review + - regex: '(MSIE) (\d+)\.(\d+).*XBLWP7' + family_replacement: 'IE Large Screen' + + #### END MAIN CASES #### + + #### SPECIAL CASES #### + - regex: '(Obigo)InternetBrowser' + - regex: '(Obigo)\-Browser' + - regex: '(Obigo|OBIGO)[^\d]*(\d+)(?:.(\d+))?' + family_replacement: 'Obigo' + + - regex: '(MAXTHON|Maxthon) (\d+)\.(\d+)' + family_replacement: 'Maxthon' + - regex: '(Maxthon|MyIE2|Uzbl|Shiira)' + v1_replacement: '0' + + - regex: '(BrowseX) \((\d+)\.(\d+)\.(\d+)' + + - regex: '(NCSA_Mosaic)/(\d+)\.(\d+)' + family_replacement: 'NCSA Mosaic' + + # Polaris/d.d is above + - regex: '(POLARIS)/(\d+)\.(\d+)' + family_replacement: 'Polaris' + - regex: '(Embider)/(\d+)\.(\d+)' + family_replacement: 'Polaris' + + - regex: '(BonEcho)/(\d+)\.(\d+)\.?([ab]?\d+)?' + family_replacement: 'Bon Echo' + + # @note: iOS / OSX Applications + - regex: '(iPod|iPhone|iPad).+Version/(\d+)\.(\d+)(?:\.(\d+))?.* Safari' + family_replacement: 'Mobile Safari' + - regex: '(iPod|iPhone|iPad).+Version/(\d+)\.(\d+)(?:\.(\d+))?' + family_replacement: 'Mobile Safari UIWebView' + - regex: '(iPod|iPhone|iPad);.*CPU.*OS (\d+)_(\d+)(?:_(\d+))?.*Mobile.* Safari' + family_replacement: 'Mobile Safari' + - regex: '(iPod|iPhone|iPad);.*CPU.*OS (\d+)_(\d+)(?:_(\d+))?.*Mobile' + family_replacement: 'Mobile Safari UIWebView' + - regex: '(iPod|iPhone|iPad).* Safari' + family_replacement: 'Mobile Safari' + - regex: '(iPod|iPhone|iPad)' + family_replacement: 'Mobile Safari UIWebView' + + - regex: '(AvantGo) (\d+).(\d+)' + + - regex: '(OneBrowser)/(\d+).(\d+)' + family_replacement: 'ONE Browser' + + - regex: '(Avant)' + v1_replacement: '1' + + # This is the Tesla Model S (see similar entry in device parsers) + - regex: '(QtCarBrowser)' + v1_replacement: '1' + + - regex: '^(iBrowser/Mini)(\d+).(\d+)' + family_replacement: 'iBrowser Mini' + - regex: '^(iBrowser|iRAPP)/(\d+).(\d+)' + + # nokia browsers + # based on: http://www.developer.nokia.com/Community/Wiki/User-Agent_headers_for_Nokia_devices + - regex: '^(Nokia)' + family_replacement: 'Nokia Services (WAP) Browser' + - regex: '(NokiaBrowser)/(\d+)\.(\d+).(\d+)\.(\d+)' + family_replacement: 'Nokia Browser' + - regex: '(NokiaBrowser)/(\d+)\.(\d+).(\d+)' + family_replacement: 'Nokia Browser' + - regex: '(NokiaBrowser)/(\d+)\.(\d+)' + family_replacement: 'Nokia Browser' + - regex: '(BrowserNG)/(\d+)\.(\d+).(\d+)' + family_replacement: 'Nokia Browser' + - regex: '(Series60)/5\.0' + family_replacement: 'Nokia Browser' + v1_replacement: '7' + v2_replacement: '0' + - regex: '(Series60)/(\d+)\.(\d+)' + family_replacement: 'Nokia OSS Browser' + - regex: '(S40OviBrowser)/(\d+)\.(\d+)\.(\d+)\.(\d+)' + family_replacement: 'Ovi Browser' + - regex: '(Nokia)[EN]?(\d+)' + + # BlackBerry devices + - regex: '(PlayBook).+RIM Tablet OS (\d+)\.(\d+)\.(\d+)' + family_replacement: 'BlackBerry WebKit' + - regex: '(Black[bB]erry|BB10).+Version/(\d+)\.(\d+)\.(\d+)' + family_replacement: 'BlackBerry WebKit' + - regex: '(Black[bB]erry)\s?(\d+)' + family_replacement: 'BlackBerry' + + - regex: '(OmniWeb)/v(\d+)\.(\d+)' + + - regex: '(Blazer)/(\d+)\.(\d+)' + family_replacement: 'Palm Blazer' + + - regex: '(Pre)/(\d+)\.(\d+)' + family_replacement: 'Palm Pre' + + # fork of Links + - regex: '(ELinks)/(\d+)\.(\d+)' + - regex: '(ELinks) \((\d+)\.(\d+)' + - regex: '(Links) \((\d+)\.(\d+)' + + - regex: '(QtWeb) Internet Browser/(\d+)\.(\d+)' + + #- regex: '\(iPad;.+(Version)/(\d+)\.(\d+)(?:\.(\d+))?.*Safari/' + # family_replacement: 'iPad' + + # Phantomjs, should go before Safari + - regex: '(PhantomJS)/(\d+)\.(\d+)\.(\d+)' + + # WebKit Nightly + - regex: '(AppleWebKit)/(\d+)\.?(\d+)?\+ .* Safari' + family_replacement: 'WebKit Nightly' + + # Safari + - regex: '(Version)/(\d+)\.(\d+)(?:\.(\d+))?.*Safari/' + family_replacement: 'Safari' + # Safari didn't provide "Version/d.d.d" prior to 3.0 + - regex: '(Safari)/\d+' + + - regex: '(OLPC)/Update(\d+)\.(\d+)' + + - regex: '(OLPC)/Update()\.(\d+)' + v1_replacement: '0' + + - regex: '(SEMC\-Browser)/(\d+)\.(\d+)' + + - regex: '(Teleca)' + family_replacement: 'Teleca Browser' + + - regex: '(Phantom)/V(\d+)\.(\d+)' + family_replacement: 'Phantom Browser' + + - regex: 'Trident(.*)rv.(\d+)\.(\d+)' + family_replacement: 'IE' + + # Espial + - regex: '(Espial)/(\d+)(?:\.(\d+))?(?:\.(\d+))?' + + # Apple Mail + + # apple mail - not directly detectable, have it after Safari stuff + - regex: '(AppleWebKit)/(\d+)\.(\d+)\.(\d+)' + family_replacement: 'AppleMail' + + # AFTER THE EDGE CASES ABOVE! + # AFTER IE11 + # BEFORE all other IE + - regex: '(Firefox)/(\d+)\.(\d+)\.(\d+)' + - regex: '(Firefox)/(\d+)\.(\d+)(pre|[ab]\d+[a-z]*)?' + + - regex: '([MS]?IE) (\d+)\.(\d+)' + family_replacement: 'IE' + + - regex: '(python-requests)/(\d+)\.(\d+)' + family_replacement: 'Python Requests' + + - regex: '(Java)[/ ]{0,1}\d+\.(\d+)\.(\d+)[_-]*([a-zA-Z0-9]+)*' + +os_parsers: + ########## + # HbbTV vendors + ########## + + # starts with the easy one : Panasonic seems consistent across years, hope it will continue + #HbbTV/1.1.1 (;Panasonic;VIERA 2011;f.532;0071-0802 2000-0000;) + #HbbTV/1.1.1 (;Panasonic;VIERA 2012;1.261;0071-3103 2000-0000;) + #HbbTV/1.2.1 (;Panasonic;VIERA 2013;3.672;4101-0003 0002-0000;) + #- regex: 'HbbTV/\d+\.\d+\.\d+ \(;(Panasonic);VIERA ([0-9]{4});' + + # Sony is consistent too but do not place year like the other + # Opera/9.80 (Linux armv7l; HbbTV/1.1.1 (; Sony; KDL32W650A; PKG3.211EUA; 2013;); ) Presto/2.12.362 Version/12.11 + # Opera/9.80 (Linux mips; U; HbbTV/1.1.1 (; Sony; KDL40HX751; PKG1.902EUA; 2012;);; en) Presto/2.10.250 Version/11.60 + # Opera/9.80 (Linux mips; U; HbbTV/1.1.1 (; Sony; KDL22EX320; PKG4.017EUA; 2011;);; en) Presto/2.7.61 Version/11.00 + #- regex: 'HbbTV/\d+\.\d+\.\d+ \(; (Sony);.*;.*; ([0-9]{4});\)' + + + # LG is consistent too, but we need to add manually the year model + #Mozilla/5.0 (Unknown; Linux armv7l) AppleWebKit/537.1+ (KHTML, like Gecko) Safari/537.1+ HbbTV/1.1.1 ( ;LGE ;NetCast 4.0 ;03.20.30 ;1.0M ;) + #Mozilla/5.0 (DirectFB; Linux armv7l) AppleWebKit/534.26+ (KHTML, like Gecko) Version/5.0 Safari/534.26+ HbbTV/1.1.1 ( ;LGE ;NetCast 3.0 ;1.0 ;1.0M ;) + - regex: 'HbbTV/\d+\.\d+\.\d+ \( ;(LG)E ;NetCast 4.0' + os_v1_replacement: '2013' + - regex: 'HbbTV/\d+\.\d+\.\d+ \( ;(LG)E ;NetCast 3.0' + os_v1_replacement: '2012' + + # Samsung is on its way of normalizing their user-agent + # HbbTV/1.1.1 (;Samsung;SmartTV2013;T-FXPDEUC-1102.2;;) WebKit + # HbbTV/1.1.1 (;Samsung;SmartTV2013;T-MST12DEUC-1102.1;;) WebKit + # HbbTV/1.1.1 (;Samsung;SmartTV2012;;;) WebKit + # HbbTV/1.1.1 (;;;;;) Maple_2011 + - regex: 'HbbTV/1.1.1 \(;;;;;\) Maple_2011' + os_replacement: 'Samsung' + os_v1_replacement: '2011' + # manage the two models of 2013 + - regex: 'HbbTV/\d+\.\d+\.\d+ \(;(Samsung);SmartTV([0-9]{4});.*FXPDEUC' + os_v2_replacement: 'UE40F7000' + - regex: 'HbbTV/\d+\.\d+\.\d+ \(;(Samsung);SmartTV([0-9]{4});.*MST12DEUC' + os_v2_replacement: 'UE32F4500' + # generic Samsung (works starting in 2012) + #- regex: 'HbbTV/\d+\.\d+\.\d+ \(;(Samsung);SmartTV([0-9]{4});' + + # Philips : not found any other way than a manual mapping + # Opera/9.80 (Linux mips; U; HbbTV/1.1.1 (; Philips; ; ; ; ) CE-HTML/1.0 NETTV/4.1.3 PHILIPSTV/1.1.1; en) Presto/2.10.250 Version/11.60 + # Opera/9.80 (Linux mips ; U; HbbTV/1.1.1 (; Philips; ; ; ; ) CE-HTML/1.0 NETTV/3.2.1; en) Presto/2.6.33 Version/10.70 + - regex: 'HbbTV/1.1.1 \(; (Philips);.*NETTV/4' + os_v1_replacement: '2013' + - regex: 'HbbTV/1.1.1 \(; (Philips);.*NETTV/3' + os_v1_replacement: '2012' + - regex: 'HbbTV/1.1.1 \(; (Philips);.*NETTV/2' + os_v1_replacement: '2011' + + # the HbbTV emulator developers use HbbTV/1.1.1 (;;;;;) firetv-firefox-plugin 1.1.20 + - regex: 'HbbTV/\d+\.\d+\.\d+.*(firetv)-firefox-plugin (\d+).(\d+).(\d+)' + os_replacement: 'FireHbbTV' + + # generic HbbTV, hoping to catch manufacturer name (always after 2nd comma) and the first string that looks like a 2011-2019 year + - regex: 'HbbTV/\d+\.\d+\.\d+ \(.*; ?([a-zA-Z]+) ?;.*(201[1-9]).*\)' + + ########## + # @note: Windows Phone needs to come before Windows NT 6.1 *and* before Android to catch cases such as: + # Mozilla/5.0 (Mobile; Windows Phone 8.1; Android 4.0; ARM; Trident/7.0; Touch; rv:11.0; IEMobile/11.0; NOKIA; Lumia 920)... + # Mozilla/5.0 (Mobile; Windows Phone 8.1; Android 4.0; ARM; Trident/7.0; Touch; rv:11.0; IEMobile/11.0; NOKIA; Lumia 920; ANZ821)... + # Mozilla/5.0 (Mobile; Windows Phone 8.1; Android 4.0; ARM; Trident/7.0; Touch; rv:11.0; IEMobile/11.0; NOKIA; Lumia 920; Orange)... + # Mozilla/5.0 (Mobile; Windows Phone 8.1; Android 4.0; ARM; Trident/7.0; Touch; rv:11.0; IEMobile/11.0; NOKIA; Lumia 920; Vodafone)... + ########## + + - regex: '(Windows Phone) (?:OS[ /])?(\d+)\.(\d+)' + + ########## + # Android + # can actually detect rooted android os. do we care? + ########## + - regex: '(Android)[ \-/](\d+)\.(\d+)(?:[.\-]([a-z0-9]+))?' + + - regex: '(Android) Donut' + os_v1_replacement: '1' + os_v2_replacement: '2' + + - regex: '(Android) Eclair' + os_v1_replacement: '2' + os_v2_replacement: '1' + + - regex: '(Android) Froyo' + os_v1_replacement: '2' + os_v2_replacement: '2' + + - regex: '(Android) Gingerbread' + os_v1_replacement: '2' + os_v2_replacement: '3' + + - regex: '(Android) Honeycomb' + os_v1_replacement: '3' + + # UCWEB + - regex: '^UCWEB.*; (Adr) (\d+)\.(\d+)(?:[.\-]([a-z0-9]+))?;' + os_replacement: 'Android' + - regex: '^UCWEB.*; (iPad OS|iPh OS) (\d+)_(\d+)(?:_(\d+))?;' + os_replacement: 'iOS' + - regex: '^UCWEB.*; (wds) (\d+)\.(\d+)(?:\.(\d+))?;' + os_replacement: 'Windows Phone' + # JUC + - regex: '^(JUC).*; ?U; ?(?:Android)?(\d+)\.(\d+)(?:[\.\-]([a-z0-9]+))?' + os_replacement: 'Android' + + ########## + # Kindle Android + ########## + - regex: '(Silk-Accelerated=[a-z]{4,5})' + os_replacement: 'Android' + + ########## + # Windows + # http://en.wikipedia.org/wiki/Windows_NT#Releases + # possibility of false positive when different marketing names share same NT kernel + # e.g. windows server 2003 and windows xp + # lots of ua strings have Windows NT 4.1 !?!?!?!? !?!? !? !????!?! !!! ??? !?!?! ? + # (very) roughly ordered in terms of frequency of occurence of regex (win xp currently most frequent, etc) + ########## + + # ie mobile desktop mode + # spoofs nt 6.1. must come before windows 7 + - regex: '(XBLWP7)' + os_replacement: 'Windows Phone' + + # @note: This needs to come before Windows NT 6.1 + - regex: '(Windows ?Mobile)' + os_replacement: 'Windows Mobile' + + - regex: '(Windows (?:NT 5\.2|NT 5\.1))' + os_replacement: 'Windows XP' + + - regex: '(Windows NT 6\.1)' + os_replacement: 'Windows 7' + + - regex: '(Windows NT 6\.0)' + os_replacement: 'Windows Vista' + + - regex: '(Win 9x 4\.90)' + os_replacement: 'Windows ME' + + - regex: '(Windows 98|Windows XP|Windows ME|Windows 95|Windows CE|Windows 7|Windows NT 4\.0|Windows Vista|Windows 2000|Windows 3.1)' + + - regex: '(Windows NT 6\.2; ARM;)' + os_replacement: 'Windows RT' + - regex: '(Windows NT 6\.2)' + os_replacement: 'Windows 8' + + - regex: '(Windows NT 6\.3; ARM;)' + os_replacement: 'Windows RT 8.1' + - regex: '(Windows NT 6\.3)' + os_replacement: 'Windows 8.1' + + - regex: '(Windows NT 6\.4)' + os_replacement: 'Windows 10' + - regex: '(Windows NT 10\.0)' + os_replacement: 'Windows 10' + + - regex: '(Windows NT 5\.0)' + os_replacement: 'Windows 2000' + + - regex: '(WinNT4.0)' + os_replacement: 'Windows NT 4.0' + + - regex: '(Windows ?CE)' + os_replacement: 'Windows CE' + + - regex: 'Win ?(95|98|3.1|NT|ME|2000)' + os_replacement: 'Windows $1' + + - regex: 'Win16' + os_replacement: 'Windows 3.1' + + - regex: 'Win32' + os_replacement: 'Windows 95' + + ########## + # Tizen OS from Samsung + # spoofs Android so pushing it above + ########## + - regex: '(Tizen)/(\d+)\.(\d+)' + + ########## + # Mac OS + # @ref: http://en.wikipedia.org/wiki/Mac_OS_X#Versions + # @ref: http://www.puredarwin.org/curious/versions + ########## + - regex: '((?:Mac ?|; )OS X)[\s/](?:(\d+)[_.](\d+)(?:[_.](\d+))?|Mach-O)' + os_replacement: 'Mac OS X' + # Leopard + - regex: ' (Dar)(win)/(9).(\d+).*\((?:i386|x86_64|Power Macintosh)\)' + os_replacement: 'Mac OS X' + os_v1_replacement: '10' + os_v2_replacement: '5' + # Snow Leopard + - regex: ' (Dar)(win)/(10).(\d+).*\((?:i386|x86_64)\)' + os_replacement: 'Mac OS X' + os_v1_replacement: '10' + os_v2_replacement: '6' + # Lion + - regex: ' (Dar)(win)/(11).(\d+).*\((?:i386|x86_64)\)' + os_replacement: 'Mac OS X' + os_v1_replacement: '10' + os_v2_replacement: '7' + # Mountain Lion + - regex: ' (Dar)(win)/(12).(\d+).*\((?:i386|x86_64)\)' + os_replacement: 'Mac OS X' + os_v1_replacement: '10' + os_v2_replacement: '8' + # Mavericks + - regex: ' (Dar)(win)/(13).(\d+).*\((?:i386|x86_64)\)' + os_replacement: 'Mac OS X' + os_v1_replacement: '10' + os_v2_replacement: '9' + # Yosemite is Darwin/14.x but patch versions are inconsistent in the Darwin string; + # more accurately covered by CFNetwork regexes downstream + + # IE on Mac doesn't specify version number + - regex: 'Mac_PowerPC' + os_replacement: 'Mac OS' + + # builds before tiger don't seem to specify version? + + # ios devices spoof (mac os x), so including intel/ppc prefixes + - regex: '(?:PPC|Intel) (Mac OS X)' + + ########## + # iOS + # http://en.wikipedia.org/wiki/IOS_version_history + ########## + # keep this above generic iOS, since AppleTV UAs contain 'CPU OS' + - regex: '(Apple\s?TV)(?:/(\d+)\.(\d+))?' + os_replacement: 'ATV OS X' + + - regex: '(CPU OS|iPhone OS|CPU iPhone) +(\d+)[_\.](\d+)(?:[_\.](\d+))?' + os_replacement: 'iOS' + + # remaining cases are mostly only opera uas, so catch opera as to not catch iphone spoofs + - regex: '(iPhone|iPad|iPod); Opera' + os_replacement: 'iOS' + + # few more stragglers + - regex: '(iPhone|iPad|iPod).*Mac OS X.*Version/(\d+)\.(\d+)' + os_replacement: 'iOS' + + # CFNetwork/Darwin - The specific CFNetwork or Darwin version determines + # whether the os maps to Mac OS, or iOS, or just Darwin. + # See: http://user-agents.me/cfnetwork-version-list + - regex: '(CFNetwork)/(5)48\.0\.3.* Darwin/11\.0\.0' + os_replacement: 'iOS' + - regex: '(CFNetwork)/(5)48\.(0)\.4.* Darwin/(1)1\.0\.0' + os_replacement: 'iOS' + - regex: '(CFNetwork)/(5)48\.(1)\.4' + os_replacement: 'iOS' + - regex: '(CFNetwork)/(4)85\.1(3)\.9' + os_replacement: 'iOS' + - regex: '(CFNetwork)/(6)09\.(1)\.4' + os_replacement: 'iOS' + - regex: '(CFNetwork)/(6)(0)9' + os_replacement: 'iOS' + - regex: '(CFNetwork)/6(7)2\.(1)\.13' + os_replacement: 'iOS' + - regex: '(CFNetwork)/6(7)2\.(1)\.(1)4' + os_replacement: 'iOS' + - regex: '(CF)(Network)/6(7)(2)\.1\.15' + os_replacement: 'iOS' + os_v1_replacement: '7' + os_v2_replacement: '1' + - regex: '(CFNetwork)/6(7)2\.(0)\.(?:2|8)' + os_replacement: 'iOS' + - regex: '(CFNetwork)/709\.1' + os_replacement: 'iOS' + os_v1_replacement: '8' + os_v2_replacement: '0.b5' + - regex: '(CF)(Network)/711\.(\d)' + os_replacement: 'iOS' + os_v1_replacement: '8' + - regex: '(CF)(Network)/(720)\.(\d)' + os_replacement: 'Mac OS X' + os_v1_replacement: '10' + os_v2_replacement: '10' + - regex: '(CF)(Network)/758\.(\d)' + os_replacement: 'iOS' + os_v1_replacement: '9' + + ########## + # CFNetwork iOS Apps + # @ref: https://en.wikipedia.org/wiki/Darwin_(operating_system)#Release_history + ########## + - regex: 'CFNetwork/.* Darwin/(9)\.\d+' + os_replacement: 'iOS' + os_v1_replacement: '1' + - regex: 'CFNetwork/.* Darwin/(10)\.\d+' + os_replacement: 'iOS' + os_v1_replacement: '4' + - regex: 'CFNetwork/.* Darwin/(11)\.\d+' + os_replacement: 'iOS' + os_v1_replacement: '5' + - regex: 'CFNetwork/.* Darwin/(13)\.\d+' + os_replacement: 'iOS' + os_v1_replacement: '6' + - regex: 'CFNetwork/6.* Darwin/(14)\.\d+' + os_replacement: 'iOS' + os_v1_replacement: '7' + - regex: 'CFNetwork/7.* Darwin/(14)\.\d+' + os_replacement: 'iOS' + os_v1_replacement: '8' + os_v2_replacement: '0' + - regex: 'CFNetwork/7.* Darwin/(15)\.\d+' + os_replacement: 'iOS' + os_v1_replacement: '9' + os_v2_replacement: '0' + # iOS Apps + - regex: '\b(iOS[ /]|iPhone(?:/| v|[ _]OS[/,]|; | OS : |\d,\d/|\d,\d; )|iPad/)(\d{1,2})[_\.](\d{1,2})(?:[_\.](\d+))?' + os_replacement: 'iOS' + + ########## + # Apple TV + ########## + - regex: '(tvOS)/(\d+).(\d+)' + os_replacement: 'tvOS' + + ########## + # Chrome OS + # if version 0.0.0, probably this stuff: + # http://code.google.com/p/chromium-os/issues/detail?id=11573 + # http://code.google.com/p/chromium-os/issues/detail?id=13790 + ########## + - regex: '(CrOS) [a-z0-9_]+ (\d+)\.(\d+)(?:\.(\d+))?' + os_replacement: 'Chrome OS' + + ########## + # Linux distros + ########## + - regex: '([Dd]ebian)' + os_replacement: 'Debian' + - regex: '(Linux Mint)(?:/(\d+))?' + - regex: '(Mandriva)(?: Linux)?/(?:[\d.-]+m[a-z]{2}(\d+).(\d))?' + + ########## + # Symbian + Symbian OS + # http://en.wikipedia.org/wiki/History_of_Symbian + ########## + - regex: '(Symbian[Oo][Ss])[/ ](\d+)\.(\d+)' + os_replacement: 'Symbian OS' + - regex: '(Symbian/3).+NokiaBrowser/7\.3' + os_replacement: 'Symbian^3 Anna' + - regex: '(Symbian/3).+NokiaBrowser/7\.4' + os_replacement: 'Symbian^3 Belle' + - regex: '(Symbian/3)' + os_replacement: 'Symbian^3' + - regex: '\b(Series 60|SymbOS|S60Version|S60V\d|S60\b)' + os_replacement: 'Symbian OS' + - regex: '(MeeGo)' + - regex: 'Symbian [Oo][Ss]' + os_replacement: 'Symbian OS' + - regex: 'Series40;' + os_replacement: 'Nokia Series 40' + - regex: 'Series30Plus;' + os_replacement: 'Nokia Series 30 Plus' + + ########## + # BlackBerry devices + ########## + - regex: '(BB10);.+Version/(\d+)\.(\d+)\.(\d+)' + os_replacement: 'BlackBerry OS' + - regex: '(Black[Bb]erry)[0-9a-z]+/(\d+)\.(\d+)\.(\d+)(?:\.(\d+))?' + os_replacement: 'BlackBerry OS' + - regex: '(Black[Bb]erry).+Version/(\d+)\.(\d+)\.(\d+)(?:\.(\d+))?' + os_replacement: 'BlackBerry OS' + - regex: '(RIM Tablet OS) (\d+)\.(\d+)\.(\d+)' + os_replacement: 'BlackBerry Tablet OS' + - regex: '(Play[Bb]ook)' + os_replacement: 'BlackBerry Tablet OS' + - regex: '(Black[Bb]erry)' + os_replacement: 'BlackBerry OS' + + ########## + # Firefox OS + ########## + - regex: '\((?:Mobile|Tablet);.+Gecko/18.0 Firefox/\d+\.\d+' + os_replacement: 'Firefox OS' + os_v1_replacement: '1' + os_v2_replacement: '0' + os_v3_replacement: '1' + + - regex: '\((?:Mobile|Tablet);.+Gecko/18.1 Firefox/\d+\.\d+' + os_replacement: 'Firefox OS' + os_v1_replacement: '1' + os_v2_replacement: '1' + + - regex: '\((?:Mobile|Tablet);.+Gecko/26.0 Firefox/\d+\.\d+' + os_replacement: 'Firefox OS' + os_v1_replacement: '1' + os_v2_replacement: '2' + + - regex: '\((?:Mobile|Tablet);.+Gecko/28.0 Firefox/\d+\.\d+' + os_replacement: 'Firefox OS' + os_v1_replacement: '1' + os_v2_replacement: '3' + + - regex: '\((?:Mobile|Tablet);.+Gecko/30.0 Firefox/\d+\.\d+' + os_replacement: 'Firefox OS' + os_v1_replacement: '1' + os_v2_replacement: '4' + + - regex: '\((?:Mobile|Tablet);.+Gecko/32.0 Firefox/\d+\.\d+' + os_replacement: 'Firefox OS' + os_v1_replacement: '2' + os_v2_replacement: '0' + + - regex: '\((?:Mobile|Tablet);.+Gecko/34.0 Firefox/\d+\.\d+' + os_replacement: 'Firefox OS' + os_v1_replacement: '2' + os_v2_replacement: '1' + + # Firefox OS Generic + - regex: '\((?:Mobile|Tablet);.+Firefox/\d+\.\d+' + os_replacement: 'Firefox OS' + + + ########## + # BREW + # yes, Brew is lower-cased for Brew MP + ########## + - regex: '(BREW)[ /](\d+)\.(\d+)\.(\d+)' + - regex: '(BREW);' + - regex: '(Brew MP|BMP)[ /](\d+)\.(\d+)\.(\d+)' + os_replacement: 'Brew MP' + - regex: 'BMP;' + os_replacement: 'Brew MP' + + ########## + # Google TV + ########## + - regex: '(GoogleTV)(?: (\d+)\.(\d+)(?:\.(\d+))?|/[\da-z]+)' + + - regex: '(WebTV)/(\d+).(\d+)' + + ########## + # Misc mobile + ########## + - regex: '(hpw|web)OS/(\d+)\.(\d+)(?:\.(\d+))?' + os_replacement: 'webOS' + - regex: '(VRE);' + + ########## + # Generic patterns + # since the majority of os cases are very specific, these go last + ########## + - regex: '(Fedora|Red Hat|PCLinuxOS|Puppy|Ubuntu|Kindle|Bada|Lubuntu|BackTrack|Slackware|(?:Free|Open|Net|\b)BSD)[/ ](\d+)\.(\d+)(?:\.(\d+)(?:\.(\d+))?)?' + + # Gentoo Linux + Kernel Version + - regex: '(Linux)[ /](\d+)\.(\d+)(?:\.(\d+))?.*gentoo' + os_replacement: 'Gentoo' + + # Opera Mini Bada + - regex: '\((Bada);' + + # just os + - regex: '(Windows|Android|WeTab|Maemo)' + - regex: '(Ubuntu|Kubuntu|Arch Linux|CentOS|Slackware|Gentoo|openSUSE|SUSE|Red Hat|Fedora|PCLinuxOS|Mageia|(?:Free|Open|Net|\b)BSD)' + # Linux + Kernel Version + - regex: '(Linux)(?:[ /](\d+)\.(\d+)(?:\.(\d+))?)?' + - regex: 'SunOS' + os_replacement: 'Solaris' + +device_parsers: + + ######### + # Mobile Spiders + # Catch the mobile crawler before checking for iPhones / Androids. + ######### + - regex: '(?:(?:iPhone|Windows CE|Android).*(?:(?:Bot|Yeti)-Mobile|YRSpider|bots?/\d|(?:bot|spider)\.html)|AdsBot-Google-Mobile.*iPhone)' + regex_flag: 'i' + device_replacement: 'Spider' + brand_replacement: 'Spider' + model_replacement: 'Smartphone' + - regex: '(?:DoCoMo|\bMOT\b|\bLG\b|Nokia|Samsung|SonyEricsson).*(?:(?:Bot|Yeti)-Mobile|bots?/\d|(?:bot|crawler)\.html|(?:jump|google|Wukong)bot|ichiro/mobile|/spider|YahooSeeker)' + regex_flag: 'i' + device_replacement: 'Spider' + brand_replacement: 'Spider' + model_replacement: 'Feature Phone' + + ######### + # WebBrowser for SmartWatch + # @ref: https://play.google.com/store/apps/details?id=se.vaggan.webbrowser&hl=en + ######### + - regex: '\bSmartWatch *\( *([^;]+) *; *([^;]+) *;' + device_replacement: '$1 $2' + brand_replacement: '$1' + model_replacement: '$2' + + ###################################################################### + # Android parsers + # + # @ref: https://support.google.com/googleplay/answer/1727131?hl=en + ###################################################################### + + # Android Application + - regex: 'Android Application[^\-]+ - (Sony) ?(Ericsson)? (.+) \w+ - ' + device_replacement: '$1 $2' + brand_replacement: '$1$2' + model_replacement: '$3' + - regex: 'Android Application[^\-]+ - (?:HTC|HUAWEI|LGE|LENOVO|MEDION|TCT) (HTC|HUAWEI|LG|LENOVO|MEDION|ALCATEL)[ _\-](.+) \w+ - ' + regex_flag: 'i' + device_replacement: '$1 $2' + brand_replacement: '$1' + model_replacement: '$2' + - regex: 'Android Application[^\-]+ - ([^ ]+) (.+) \w+ - ' + device_replacement: '$1 $2' + brand_replacement: '$1' + model_replacement: '$2' + + ######### + # 3Q + # @ref: http://www.3q-int.com/ + ######### + - regex: '; *([BLRQ]C\d{4}[A-Z]+) +Build/' + device_replacement: '3Q $1' + brand_replacement: '3Q' + model_replacement: '$1' + - regex: '; *(?:3Q_)([^;/]+) +Build' + device_replacement: '3Q $1' + brand_replacement: '3Q' + model_replacement: '$1' + + ######### + # Acer + # @ref: http://us.acer.com/ac/en/US/content/group/tablets + ######### + - regex: 'Android [34].*; *(A100|A101|A110|A200|A210|A211|A500|A501|A510|A511|A700(?: Lite| 3G)?|A701|B1-A71|A1-\d{3}|B1-\d{3}|V360|V370|W500|W500P|W501|W501P|W510|W511|W700|Slider SL101|DA22[^;/]+) Build' + device_replacement: '$1' + brand_replacement: 'Acer' + model_replacement: '$1' + - regex: '; *Acer Iconia Tab ([^;/]+) Build' + device_replacement: '$1' + brand_replacement: 'Acer' + model_replacement: '$1' + - regex: '; *(Z1[1235]0|E320[^/]*|S500|S510|Liquid[^;/]*|Iconia A\d+) Build' + device_replacement: '$1' + brand_replacement: 'Acer' + model_replacement: '$1' + - regex: '; *(Acer |ACER )([^;/]+) Build' + device_replacement: '$1$2' + brand_replacement: 'Acer' + model_replacement: '$2' + + ######### + # Advent + # @ref: https://en.wikipedia.org/wiki/Advent_Vega + # @note: VegaBean and VegaComb (names derived from jellybean, honeycomb) are + # custom ROM builds for Vega + ######### + - regex: '; *(Advent )?(Vega(?:Bean|Comb)?).* Build' + device_replacement: '$1$2' + brand_replacement: 'Advent' + model_replacement: '$2' + + ######### + # Ainol + # @ref: http://www.ainol.com/plugin.php?identifier=ainol&module=product + ######### + - regex: '; *(Ainol )?((?:NOVO|[Nn]ovo)[^;/]+) Build' + device_replacement: '$1$2' + brand_replacement: 'Ainol' + model_replacement: '$2' + + ######### + # Airis + # @ref: http://airis.es/Tienda/Default.aspx?idG=001 + ######### + - regex: '; *AIRIS[ _\-]?([^/;\)]+) *(?:;|\)|Build)' + regex_flag: 'i' + device_replacement: '$1' + brand_replacement: 'Airis' + model_replacement: '$1' + - regex: '; *(OnePAD[^;/]+) Build' + regex_flag: 'i' + device_replacement: '$1' + brand_replacement: 'Airis' + model_replacement: '$1' + + ######### + # Airpad + # @ref: ?? + ######### + - regex: '; *Airpad[ \-]([^;/]+) Build' + device_replacement: 'Airpad $1' + brand_replacement: 'Airpad' + model_replacement: '$1' + + ######### + # Alcatel - TCT + # @ref: http://www.alcatelonetouch.com/global-en/products/smartphones.html + ######### + - regex: '; *(one ?touch) (EVO7|T10|T20) Build' + device_replacement: 'Alcatel One Touch $2' + brand_replacement: 'Alcatel' + model_replacement: 'One Touch $2' + - regex: '; *(?:alcatel[ _])?(?:(?:one[ _]?touch[ _])|ot[ \-])([^;/]+);? Build' + regex_flag: 'i' + device_replacement: 'Alcatel One Touch $1' + brand_replacement: 'Alcatel' + model_replacement: 'One Touch $1' + - regex: '; *(TCL)[ _]([^;/]+) Build' + device_replacement: '$1 $2' + brand_replacement: '$1' + model_replacement: '$2' + # operator specific models + - regex: '; *(Vodafone Smart II|Optimus_Madrid) Build' + device_replacement: 'Alcatel $1' + brand_replacement: 'Alcatel' + model_replacement: '$1' + - regex: '; *BASE_Lutea_3 Build' + device_replacement: 'Alcatel One Touch 998' + brand_replacement: 'Alcatel' + model_replacement: 'One Touch 998' + - regex: '; *BASE_Varia Build' + device_replacement: 'Alcatel One Touch 918D' + brand_replacement: 'Alcatel' + model_replacement: 'One Touch 918D' + + ######### + # Allfine + # @ref: http://www.myallfine.com/Products.asp + ######### + - regex: '; *((?:FINE|Fine)\d[^;/]+) Build' + device_replacement: '$1' + brand_replacement: 'Allfine' + model_replacement: '$1' + + ######### + # Allview + # @ref: http://www.allview.ro/produse/droseries/lista-tablete-pc/ + ######### + - regex: '; *(ALLVIEW[ _]?|Allview[ _]?)((?:Speed|SPEED).*) Build/' + device_replacement: '$1$2' + brand_replacement: 'Allview' + model_replacement: '$2' + - regex: '; *(ALLVIEW[ _]?|Allview[ _]?)?(AX1_Shine|AX2_Frenzy) Build' + device_replacement: '$1$2' + brand_replacement: 'Allview' + model_replacement: '$2' + - regex: '; *(ALLVIEW[ _]?|Allview[ _]?)([^;/]*) Build' + device_replacement: '$1$2' + brand_replacement: 'Allview' + model_replacement: '$2' + + ######### + # Allwinner + # @ref: http://www.allwinner.com/ + # @models: A31 (13.3"),A20,A10, + ######### + - regex: '; *(A13-MID) Build' + device_replacement: '$1' + brand_replacement: 'Allwinner' + model_replacement: '$1' + - regex: '; *(Allwinner)[ _\-]?([^;/]+) Build' + device_replacement: '$1 $2' + brand_replacement: 'Allwinner' + model_replacement: '$1' + + ######### + # Amaway + # @ref: http://www.amaway.cn/ + ######### + - regex: '; *(A651|A701B?|A702|A703|A705|A706|A707|A711|A712|A713|A717|A722|A785|A801|A802|A803|A901|A902|A1002|A1003|A1006|A1007|A9701|A9703|Q710|Q80) Build' + device_replacement: '$1' + brand_replacement: 'Amaway' + model_replacement: '$1' + + ######### + # Amoi + # @ref: http://www.amoi.com/en/prd/prd_index.jspx + ######### + - regex: '; *(?:AMOI|Amoi)[ _]([^;/]+) Build' + device_replacement: 'Amoi $1' + brand_replacement: 'Amoi' + model_replacement: '$1' + - regex: '^(?:AMOI|Amoi)[ _]([^;/]+) Linux' + device_replacement: 'Amoi $1' + brand_replacement: 'Amoi' + model_replacement: '$1' + + ######### + # Aoc + # @ref: http://latin.aoc.com/media_tablet + ######### + - regex: '; *(MW(?:0[789]|10)[^;/]+) Build' + device_replacement: '$1' + brand_replacement: 'Aoc' + model_replacement: '$1' + + ######### + # Aoson + # @ref: http://www.luckystar.com.cn/en/mid.aspx?page=1 + # @ref: http://www.luckystar.com.cn/en/mobiletel.aspx?page=1 + # @note: brand owned by luckystar + ######### + - regex: '; *(G7|M1013|M1015G|M11[CG]?|M-?12[B]?|M15|M19[G]?|M30[ACQ]?|M31[GQ]|M32|M33[GQ]|M36|M37|M38|M701T|M710|M712B|M713|M715G|M716G|M71(?:G|GS|T)?|M72[T]?|M73[T]?|M75[GT]?|M77G|M79T|M7L|M7LN|M81|M810|M81T|M82|M92|M92KS|M92S|M717G|M721|M722G|M723|M725G|M739|M785|M791|M92SK|M93D) Build' + device_replacement: 'Aoson $1' + brand_replacement: 'Aoson' + model_replacement: '$1' + - regex: '; *Aoson ([^;/]+) Build' + regex_flag: 'i' + device_replacement: 'Aoson $1' + brand_replacement: 'Aoson' + model_replacement: '$1' + + ######### + # Apanda + # @ref: http://www.apanda.com.cn/ + ######### + - regex: '; *[Aa]panda[ _\-]([^;/]+) Build' + device_replacement: 'Apanda $1' + brand_replacement: 'Apanda' + model_replacement: '$1' + + ######### + # Archos + # @ref: http://www.archos.com/de/products/tablets.html + # @ref: http://www.archos.com/de/products/smartphones/index.html + ######### + - regex: '; *(?:ARCHOS|Archos) ?(GAMEPAD.*?)(?: Build|[;/\(\)\-])' + device_replacement: 'Archos $1' + brand_replacement: 'Archos' + model_replacement: '$1' + - regex: 'ARCHOS; GOGI; ([^;]+);' + device_replacement: 'Archos $1' + brand_replacement: 'Archos' + model_replacement: '$1' + - regex: '(?:ARCHOS|Archos)[ _]?(.*?)(?: Build|[;/\(\)\-]|$)' + device_replacement: 'Archos $1' + brand_replacement: 'Archos' + model_replacement: '$1' + - regex: '; *(AN(?:7|8|9|10|13)[A-Z0-9]{1,4}) Build' + device_replacement: 'Archos $1' + brand_replacement: 'Archos' + model_replacement: '$1' + - regex: '; *(A28|A32|A43|A70(?:BHT|CHT|HB|S|X)|A101(?:B|C|IT)|A7EB|A7EB-WK|101G9|80G9) Build' + device_replacement: 'Archos $1' + brand_replacement: 'Archos' + model_replacement: '$1' + + ######### + # A-rival + # @ref: http://www.a-rival.de/de/ + ######### + - regex: '; *(PAD-FMD[^;/]+) Build' + device_replacement: '$1' + brand_replacement: 'Arival' + model_replacement: '$1' + - regex: '; *(BioniQ) ?([^;/]+) Build' + device_replacement: '$1 $2' + brand_replacement: 'Arival' + model_replacement: '$1 $2' + + ######### + # Arnova + # @ref: http://arnovatech.com/ + ######### + - regex: '; *(AN\d[^;/]+|ARCHM\d+) Build' + device_replacement: 'Arnova $1' + brand_replacement: 'Arnova' + model_replacement: '$1' + - regex: '; *(?:ARNOVA|Arnova) ?([^;/]+) Build' + device_replacement: 'Arnova $1' + brand_replacement: 'Arnova' + model_replacement: '$1' + + ######### + # Assistant + # @ref: http://www.assistant.ua + ######### + - regex: '; *(?:ASSISTANT )?(AP)-?([1789]\d{2}[A-Z]{0,2}|80104) Build' + device_replacement: 'Assistant $1-$2' + brand_replacement: 'Assistant' + model_replacement: '$1-$2' + + ######### + # Asus + # @ref: http://www.asus.com/uk/Tablets_Mobile/ + ######### + - regex: '; *(ME17\d[^;/]*|ME3\d{2}[^;/]+|K00[A-Z]|Nexus 10|Nexus 7(?: 2013)?|PadFone[^;/]*|Transformer[^;/]*|TF\d{3}[^;/]*|eeepc) Build' + device_replacement: 'Asus $1' + brand_replacement: 'Asus' + model_replacement: '$1' + - regex: '; *ASUS[ _]*([^;/]+) Build' + device_replacement: 'Asus $1' + brand_replacement: 'Asus' + model_replacement: '$1' + + ######### + # Garmin-Asus + ######### + - regex: '; *Garmin-Asus ([^;/]+) Build' + device_replacement: 'Garmin-Asus $1' + brand_replacement: 'Garmin-Asus' + model_replacement: '$1' + - regex: '; *(Garminfone) Build' + device_replacement: 'Garmin $1' + brand_replacement: 'Garmin-Asus' + model_replacement: '$1' + + ######### + # Attab + # @ref: http://www.theattab.com/ + ######### + - regex: '; (@TAB-[^;/]+) Build' + device_replacement: '$1' + brand_replacement: 'Attab' + model_replacement: '$1' + + ######### + # Audiosonic + # @ref: ?? + # @note: Take care with Docomo T-01 Toshiba + ######### + - regex: '; *(T-(?:07|[^0]\d)[^;/]+) Build' + device_replacement: '$1' + brand_replacement: 'Audiosonic' + model_replacement: '$1' + + ######### + # Axioo + # @ref: http://www.axiooworld.com/ww/index.php + ######### + - regex: '; *(?:Axioo[ _\-]([^;/]+)|(picopad)[ _\-]([^;/]+)) Build' + regex_flag: 'i' + device_replacement: 'Axioo $1$2 $3' + brand_replacement: 'Axioo' + model_replacement: '$1$2 $3' + + ######### + # Azend + # @ref: http://azendcorp.com/index.php/products/portable-electronics + ######### + - regex: '; *(V(?:100|700|800)[^;/]*) Build' + device_replacement: '$1' + brand_replacement: 'Azend' + model_replacement: '$1' + + ######### + # Bak + # @ref: http://www.bakinternational.com/produtos.php?cat=80 + ######### + - regex: '; *(IBAK\-[^;/]*) Build' + regex_flag: 'i' + device_replacement: '$1' + brand_replacement: 'Bak' + model_replacement: '$1' + + ######### + # Bedove + # @ref: http://www.bedove.com/product.html + # @models: HY6501|HY5001|X12|X21|I5 + ######### + - regex: '; *(HY5001|HY6501|X12|X21|I5) Build' + device_replacement: 'Bedove $1' + brand_replacement: 'Bedove' + model_replacement: '$1' + + ######### + # Benss + # @ref: http://www.benss.net/ + ######### + - regex: '; *(JC-[^;/]*) Build' + device_replacement: 'Benss $1' + brand_replacement: 'Benss' + model_replacement: '$1' + + ######### + # Blackberry + # @ref: http://uk.blackberry.com/ + # @note: Android Apps seams to be used here + ######### + - regex: '; *(BB) ([^;/]+) Build' + device_replacement: '$1 $2' + brand_replacement: 'Blackberry' + model_replacement: '$2' + + ######### + # Blackbird + # @ref: http://iblackbird.co.kr + ######### + - regex: '; *(BlackBird)[ _](I8.*) Build' + device_replacement: '$1 $2' + brand_replacement: '$1' + model_replacement: '$2' + - regex: '; *(BlackBird)[ _](.*) Build' + device_replacement: '$1 $2' + brand_replacement: '$1' + model_replacement: '$2' + + ######### + # Blaupunkt + # @ref: http://www.blaupunkt.com + ######### + # Endeavour + - regex: '; *([0-9]+BP[EM][^;/]*|Endeavour[^;/]+) Build' + device_replacement: 'Blaupunkt $1' + brand_replacement: 'Blaupunkt' + model_replacement: '$1' + + ######### + # Blu + # @ref: http://bluproducts.com + ######### + - regex: '; *((?:BLU|Blu)[ _\-])([^;/]+) Build' + device_replacement: '$1$2' + brand_replacement: 'Blu' + model_replacement: '$2' + # BMOBILE = operator branded device + - regex: '; *(?:BMOBILE )?(Blu|BLU|DASH [^;/]+|VIVO 4\.3|TANK 4\.5) Build' + device_replacement: '$1' + brand_replacement: 'Blu' + model_replacement: '$1' + + ######### + # Blusens + # @ref: http://www.blusens.com/es/?sg=1&sv=al&roc=1 + ######### + # tablet + - regex: '; *(TOUCH\d[^;/]+) Build' + device_replacement: '$1' + brand_replacement: 'Blusens' + model_replacement: '$1' + + ######### + # Bmobile + # @ref: http://bmobile.eu.com/?categoria=smartphones-2 + # @note: Might collide with Maxx as AX is used also there. + ######### + # smartphone + - regex: '; *(AX5\d+) Build' + device_replacement: '$1' + brand_replacement: 'Bmobile' + model_replacement: '$1' + + ######### + # bq + # @ref: http://bqreaders.com + ######### + - regex: '; *([Bb]q) ([^;/]+);? Build' + device_replacement: '$1 $2' + brand_replacement: 'bq' + model_replacement: '$2' + - regex: '; *(Maxwell [^;/]+) Build' + device_replacement: '$1' + brand_replacement: 'bq' + model_replacement: '$1' + + ######### + # Braun Phototechnik + # @ref: http://www.braun-phototechnik.de/en/products/list/~pcat.250/Tablet-PC.html + ######### + - regex: '; *((?:B-Tab|B-TAB) ?\d[^;/]+) Build' + device_replacement: '$1' + brand_replacement: 'Braun' + model_replacement: '$1' + + ######### + # Broncho + # @ref: http://www.broncho.cn/ + ######### + - regex: '; *(Broncho) ([^;/]+) Build' + device_replacement: '$1 $2' + brand_replacement: '$1' + model_replacement: '$2' + + ######### + # Captiva + # @ref: http://www.captiva-power.de + ######### + - regex: '; *CAPTIVA ([^;/]+) Build' + device_replacement: 'Captiva $1' + brand_replacement: 'Captiva' + model_replacement: '$1' + + ######### + # Casio + # @ref: http://www.casiogzone.com/ + ######### + - regex: '; *(C771|CAL21|IS11CA) Build' + device_replacement: '$1' + brand_replacement: 'Casio' + model_replacement: '$1' + + ######### + # Cat + # @ref: http://www.cat-sound.com + ######### + - regex: '; *(?:Cat|CAT) ([^;/]+) Build' + device_replacement: 'Cat $1' + brand_replacement: 'Cat' + model_replacement: '$1' + - regex: '; *(?:Cat)(Nova.*) Build' + device_replacement: 'Cat $1' + brand_replacement: 'Cat' + model_replacement: '$1' + - regex: '; *(INM8002KP|ADM8000KP_[AB]) Build' + device_replacement: '$1' + brand_replacement: 'Cat' + model_replacement: 'Tablet PHOENIX 8.1J0' + + ######### + # Celkon + # @ref: http://www.celkonmobiles.com/?_a=products + # @models: A10, A19Q, A101, A105, A107, A107\+, A112, A118, A119, A119Q, A15, A19, A20, A200, A220, A225, A22 Race, A27, A58, A59, A60, A62, A63, A64, A66, A67, A69, A75, A77, A79, A8\+, A83, A85, A86, A87, A89 Ultima, A9\+, A90, A900, A95, A97i, A98, AR 40, AR 45, AR 50, ML5 + ######### + - regex: '; *(?:[Cc]elkon[ _\*]|CELKON[ _\*])([^;/\)]+) ?(?:Build|;|\))' + device_replacement: '$1' + brand_replacement: 'Celkon' + model_replacement: '$1' + - regex: 'Build/(?:[Cc]elkon)+_?([^;/_\)]+)' + device_replacement: '$1' + brand_replacement: 'Celkon' + model_replacement: '$1' + - regex: '; *(CT)-?(\d+) Build' + device_replacement: '$1$2' + brand_replacement: 'Celkon' + model_replacement: '$1$2' + # smartphones + - regex: '; *(A19|A19Q|A105|A107[^;/\)]*) ?(?:Build|;|\))' + device_replacement: '$1' + brand_replacement: 'Celkon' + model_replacement: '$1' + + ######### + # ChangJia + # @ref: http://www.cjshowroom.com/eproducts.aspx?classcode=004001001 + # @brief: China manufacturer makes tablets for different small brands + # (eg. http://www.zeepad.net/index.html) + ######### + - regex: '; *(TPC[0-9]{4,5}) Build' + device_replacement: '$1' + brand_replacement: 'ChangJia' + model_replacement: '$1' + + ######### + # Cloudfone + # @ref: http://www.cloudfonemobile.com/ + ######### + - regex: '; *(Cloudfone)[ _](Excite)([^ ][^;/]+) Build' + device_replacement: '$1 $2 $3' + brand_replacement: 'Cloudfone' + model_replacement: '$1 $2 $3' + - regex: '; *(Excite|ICE)[ _](\d+[^;/]+) Build' + device_replacement: 'Cloudfone $1 $2' + brand_replacement: 'Cloudfone' + model_replacement: 'Cloudfone $1 $2' + - regex: '; *(Cloudfone|CloudPad)[ _]([^;/]+) Build' + device_replacement: '$1 $2' + brand_replacement: 'Cloudfone' + model_replacement: '$1 $2' + + ######### + # Cmx + # @ref: http://cmx.at/de/ + ######### + - regex: '; *((?:Aquila|Clanga|Rapax)[^;/]+) Build' + regex_flag: 'i' + device_replacement: '$1' + brand_replacement: 'Cmx' + model_replacement: '$1' + + ######### + # CobyKyros + # @ref: http://cobykyros.com + # @note: Be careful with MID\d{3} from MpMan or Manta + ######### + - regex: '; *(?:CFW-|Kyros )?(MID[0-9]{4}(?:[ABC]|SR|TV)?)(\(3G\)-4G| GB 8K| 3G| 8K| GB)? *(?:Build|[;\)])' + device_replacement: 'CobyKyros $1$2' + brand_replacement: 'CobyKyros' + model_replacement: '$1$2' + + ######### + # Coolpad + # @ref: ?? + ######### + - regex: '; *([^;/]*)Coolpad[ _]([^;/]+) Build' + device_replacement: '$1$2' + brand_replacement: 'Coolpad' + model_replacement: '$1$2' + + ######### + # Cube + # @ref: http://www.cube-tablet.com/buy-products.html + ######### + - regex: '; *(CUBE[ _])?([KU][0-9]+ ?GT.*|A5300) Build' + regex_flag: 'i' + device_replacement: '$1$2' + brand_replacement: 'Cube' + model_replacement: '$2' + + ######### + # Cubot + # @ref: http://www.cubotmall.com/ + ######### + - regex: '; *CUBOT ([^;/]+) Build' + regex_flag: 'i' + device_replacement: '$1' + brand_replacement: 'Cubot' + model_replacement: '$1' + - regex: '; *(BOBBY) Build' + regex_flag: 'i' + device_replacement: '$1' + brand_replacement: 'Cubot' + model_replacement: '$1' + + ######### + # Danew + # @ref: http://www.danew.com/produits-tablette.php + ######### + - regex: '; *(Dslide [^;/]+) Build' + device_replacement: '$1' + brand_replacement: 'Danew' + model_replacement: '$1' + + ######### + # Dell + # @ref: http://www.dell.com + # @ref: http://www.softbank.jp/mobile/support/product/101dl/ + # @ref: http://www.softbank.jp/mobile/support/product/001dl/ + # @ref: http://developer.emnet.ne.jp/android.html + # @ref: http://www.dell.com/in/p/mobile-xcd28/pd + # @ref: http://www.dell.com/in/p/mobile-xcd35/pd + ######### + - regex: '; *(XCD)[ _]?(28|35) Build' + device_replacement: 'Dell $1$2' + brand_replacement: 'Dell' + model_replacement: '$1$2' + - regex: '; *(001DL) Build' + device_replacement: 'Dell $1' + brand_replacement: 'Dell' + model_replacement: 'Streak' + - regex: '; *(?:Dell|DELL) (Streak) Build' + device_replacement: 'Dell $1' + brand_replacement: 'Dell' + model_replacement: 'Streak' + - regex: '; *(101DL|GS01|Streak Pro[^;/]*) Build' + device_replacement: 'Dell $1' + brand_replacement: 'Dell' + model_replacement: 'Streak Pro' + - regex: '; *([Ss]treak ?7) Build' + device_replacement: 'Dell $1' + brand_replacement: 'Dell' + model_replacement: 'Streak 7' + - regex: '; *(Mini-3iX) Build' + device_replacement: 'Dell $1' + brand_replacement: 'Dell' + model_replacement: '$1' + - regex: '; *(?:Dell|DELL)[ _](Aero|Venue|Thunder|Mini.*|Streak[ _]Pro) Build' + device_replacement: 'Dell $1' + brand_replacement: 'Dell' + model_replacement: '$1' + - regex: '; *Dell[ _]([^;/]+) Build' + device_replacement: 'Dell $1' + brand_replacement: 'Dell' + model_replacement: '$1' + - regex: '; *Dell ([^;/]+) Build' + device_replacement: 'Dell $1' + brand_replacement: 'Dell' + model_replacement: '$1' + + ######### + # Denver + # @ref: http://www.denver-electronics.com/tablets1/ + ######### + - regex: '; *(TA[CD]-\d+[^;/]*) Build' + device_replacement: '$1' + brand_replacement: 'Denver' + model_replacement: '$1' + + ######### + # Dex + # @ref: http://dex.ua/ + ######### + - regex: '; *(iP[789]\d{2}(?:-3G)?|IP10\d{2}(?:-8GB)?) Build' + device_replacement: '$1' + brand_replacement: 'Dex' + model_replacement: '$1' + + ######### + # DNS AirTab + # @ref: http://www.dns-shop.ru/ + ######### + - regex: '; *(AirTab)[ _\-]([^;/]+) Build' + device_replacement: '$1 $2' + brand_replacement: 'DNS' + model_replacement: '$1 $2' + + ######### + # Docomo (Operator Branded Device) + # @ref: http://www.ipentec.com/document/document.aspx?page=android-useragent + ######### + - regex: '; *(F\-\d[^;/]+) Build' + device_replacement: '$1' + brand_replacement: 'Fujitsu' + model_replacement: '$1' + - regex: '; *(HT-03A) Build' + device_replacement: '$1' + brand_replacement: 'HTC' + model_replacement: 'Magic' + - regex: '; *(HT\-\d[^;/]+) Build' + device_replacement: '$1' + brand_replacement: 'HTC' + model_replacement: '$1' + - regex: '; *(L\-\d[^;/]+) Build' + device_replacement: '$1' + brand_replacement: 'LG' + model_replacement: '$1' + - regex: '; *(N\-\d[^;/]+) Build' + device_replacement: '$1' + brand_replacement: 'Nec' + model_replacement: '$1' + - regex: '; *(P\-\d[^;/]+) Build' + device_replacement: '$1' + brand_replacement: 'Panasonic' + model_replacement: '$1' + - regex: '; *(SC\-\d[^;/]+) Build' + device_replacement: '$1' + brand_replacement: 'Samsung' + model_replacement: '$1' + - regex: '; *(SH\-\d[^;/]+) Build' + device_replacement: '$1' + brand_replacement: 'Sharp' + model_replacement: '$1' + - regex: '; *(SO\-\d[^;/]+) Build' + device_replacement: '$1' + brand_replacement: 'SonyEricsson' + model_replacement: '$1' + - regex: '; *(T\-0[12][^;/]+) Build' + device_replacement: '$1' + brand_replacement: 'Toshiba' + model_replacement: '$1' + + ######### + # DOOV + # @ref: http://www.doov.com.cn/ + ######### + - regex: '; *(DOOV)[ _]([^;/]+) Build' + device_replacement: '$1 $2' + brand_replacement: 'DOOV' + model_replacement: '$2' + + ######### + # Enot + # @ref: http://www.enot.ua/ + ######### + - regex: '; *(Enot|ENOT)[ -]?([^;/]+) Build' + device_replacement: '$1 $2' + brand_replacement: 'Enot' + model_replacement: '$2' + + ######### + # Evercoss + # @ref: http://evercoss.com/android/ + ######### + - regex: '; *[^;/]+ Build/(?:CROSS|Cross)+[ _\-]([^\)]+)' + device_replacement: 'CROSS $1' + brand_replacement: 'Evercoss' + model_replacement: 'Cross $1' + - regex: '; *(CROSS|Cross)[ _\-]([^;/]+) Build' + device_replacement: '$1 $2' + brand_replacement: 'Evercoss' + model_replacement: 'Cross $2' + + ######### + # Explay + # @ref: http://explay.ru/ + ######### + - regex: '; *Explay[_ ](.+?)(?:[\)]| Build)' + device_replacement: '$1' + brand_replacement: 'Explay' + model_replacement: '$1' + + ######### + # Fly + # @ref: http://www.fly-phone.com/ + ######### + - regex: '; *(IQ.*) Build' + device_replacement: '$1' + brand_replacement: 'Fly' + model_replacement: '$1' + - regex: '; *(Fly|FLY)[ _](IQ[^;]+|F[34]\d+[^;]*);? Build' + device_replacement: '$1 $2' + brand_replacement: 'Fly' + model_replacement: '$2' + + ######### + # Fujitsu + # @ref: http://www.fujitsu.com/global/ + ######### + - regex: '; *(M532|Q572|FJL21) Build/' + device_replacement: '$1' + brand_replacement: 'Fujitsu' + model_replacement: '$1' + + ######### + # Galapad + # @ref: http://www.galapad.net/product.html + ######### + - regex: '; *(G1) Build' + device_replacement: '$1' + brand_replacement: 'Galapad' + model_replacement: '$1' + + ######### + # Geeksphone + # @ref: http://www.geeksphone.com/ + ######### + - regex: '; *(Geeksphone) ([^;/]+) Build' + device_replacement: '$1 $2' + brand_replacement: '$1' + model_replacement: '$2' + + ######### + # Gfive + # @ref: http://www.gfivemobile.com/en + ######### + #- regex: '; *(G\'?FIVE) ([^;/]+) Build' # there is a problem with python yaml parser here + - regex: '; *(G[^F]?FIVE) ([^;/]+) Build' + device_replacement: '$1 $2' + brand_replacement: 'Gfive' + model_replacement: '$2' + + ######### + # Gionee + # @ref: http://www.gionee.com/ + ######### + - regex: '; *(Gionee)[ _\-]([^;/]+)(?:/[^;/]+)? Build' + regex_flag: 'i' + device_replacement: '$1 $2' + brand_replacement: 'Gionee' + model_replacement: '$2' + - regex: '; *(GN\d+[A-Z]?|INFINITY_PASSION|Ctrl_V1) Build' + device_replacement: 'Gionee $1' + brand_replacement: 'Gionee' + model_replacement: '$1' + - regex: '; *(E3) Build/JOP40D' + device_replacement: 'Gionee $1' + brand_replacement: 'Gionee' + model_replacement: '$1' + + ######### + # GoClever + # @ref: http://www.goclever.com + ######### + - regex: '; *((?:FONE|QUANTUM|INSIGNIA) \d+[^;/]*|PLAYTAB) Build' + device_replacement: 'GoClever $1' + brand_replacement: 'GoClever' + model_replacement: '$1' + - regex: '; *GOCLEVER ([^;/]+) Build' + device_replacement: 'GoClever $1' + brand_replacement: 'GoClever' + model_replacement: '$1' + + ######### + # Google + # @ref: http://www.google.de/glass/start/ + ######### + - regex: '; *(Glass \d+) Build' + device_replacement: '$1' + brand_replacement: 'Google' + model_replacement: '$1' + + ######### + # Gigabyte + # @ref: http://gsmart.gigabytecm.com/en/ + ######### + - regex: '; *(GSmart)[ -]([^/]+) Build' + device_replacement: '$1 $2' + brand_replacement: 'Gigabyte' + model_replacement: '$1 $2' + + ######### + # Freescale development boards + # @ref: http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=IMX53QSB + ######### + - regex: '; *(imx5[13]_[^/]+) Build' + device_replacement: 'Freescale $1' + brand_replacement: 'Freescale' + model_replacement: '$1' + + ######### + # Haier + # @ref: http://www.haier.com/ + # @ref: http://www.haier.com/de/produkte/tablet/ + ######### + - regex: '; *Haier[ _\-]([^/]+) Build' + device_replacement: 'Haier $1' + brand_replacement: 'Haier' + model_replacement: '$1' + - regex: '; *(PAD1016) Build' + device_replacement: 'Haipad $1' + brand_replacement: 'Haipad' + model_replacement: '$1' + + ######### + # Haipad + # @ref: http://www.haipad.net/ + # @models: V7P|M7SM7S|M9XM9X|M7XM7X|M9|M8|M7-M|M1002|M7|M701 + ######### + - regex: '; *(M701|M7|M8|M9) Build' + device_replacement: 'Haipad $1' + brand_replacement: 'Haipad' + model_replacement: '$1' + + ######### + # Hannspree + # @ref: http://www.hannspree.eu/ + # @models: SN10T1|SN10T2|SN70T31B|SN70T32W + ######### + - regex: '; *(SN\d+T[^;\)/]*)(?: Build|[;\)])' + device_replacement: 'Hannspree $1' + brand_replacement: 'Hannspree' + model_replacement: '$1' + + ######### + # HCLme + # @ref: http://www.hclmetablet.com/india/ + ######### + - regex: 'Build/HCL ME Tablet ([^;\)]+)[\);]' + device_replacement: 'HCLme $1' + brand_replacement: 'HCLme' + model_replacement: '$1' + - regex: '; *([^;\/]+) Build/HCL' + device_replacement: 'HCLme $1' + brand_replacement: 'HCLme' + model_replacement: '$1' + + ######### + # Hena + # @ref: http://www.henadigital.com/en/product/index.asp?id=6 + ######### + - regex: '; *(MID-?\d{4}C[EM]) Build' + device_replacement: 'Hena $1' + brand_replacement: 'Hena' + model_replacement: '$1' + + ######### + # Hisense + # @ref: http://www.hisense.com/ + ######### + - regex: '; *(EG\d{2,}|HS-[^;/]+|MIRA[^;/]+) Build' + device_replacement: 'Hisense $1' + brand_replacement: 'Hisense' + model_replacement: '$1' + - regex: '; *(andromax[^;/]+) Build' + regex_flag: 'i' + device_replacement: 'Hisense $1' + brand_replacement: 'Hisense' + model_replacement: '$1' + + ######### + # hitech + # @ref: http://www.hitech-mobiles.com/ + ######### + - regex: '; *(?:AMAZE[ _](S\d+)|(S\d+)[ _]AMAZE) Build' + device_replacement: 'AMAZE $1$2' + brand_replacement: 'hitech' + model_replacement: 'AMAZE $1$2' + + ######### + # HP + # @ref: http://www.hp.com/ + ######### + - regex: '; *(PlayBook) Build' + device_replacement: 'HP $1' + brand_replacement: 'HP' + model_replacement: '$1' + - regex: '; *HP ([^/]+) Build' + device_replacement: 'HP $1' + brand_replacement: 'HP' + model_replacement: '$1' + - regex: '; *([^/]+_tenderloin) Build' + device_replacement: 'HP TouchPad' + brand_replacement: 'HP' + model_replacement: 'TouchPad' + + ######### + # Huawei + # @ref: http://www.huaweidevice.com + # @note: Needs to be before HTC due to Desire HD Build on U8815 + ######### + - regex: '; *(HUAWEI |Huawei-)?([UY][^;/]+) Build/(?:Huawei|HUAWEI)([UY][^\);]+)\)' + device_replacement: '$1$2' + brand_replacement: 'Huawei' + model_replacement: '$2' + - regex: '; *([^;/]+) Build[/ ]Huawei(MT1-U06|[A-Z]+\d+[^\);]+)[^\);]*\)' + device_replacement: '$1' + brand_replacement: 'Huawei' + model_replacement: '$2' + - regex: '; *(S7|M860) Build' + device_replacement: '$1' + brand_replacement: 'Huawei' + model_replacement: '$1' + - regex: '; *((?:HUAWEI|Huawei)[ \-]?)(MediaPad) Build' + device_replacement: '$1$2' + brand_replacement: 'Huawei' + model_replacement: '$2' + - regex: '; *((?:HUAWEI[ _]?|Huawei[ _])?Ascend[ _])([^;/]+) Build' + device_replacement: '$1$2' + brand_replacement: 'Huawei' + model_replacement: '$2' + - regex: '; *((?:HUAWEI|Huawei)[ _\-]?)((?:G700-|MT-)[^;/]+) Build' + device_replacement: '$1$2' + brand_replacement: 'Huawei' + model_replacement: '$2' + - regex: '; *((?:HUAWEI|Huawei)[ _\-]?)([^;/]+) Build' + device_replacement: '$1$2' + brand_replacement: 'Huawei' + model_replacement: '$2' + - regex: '; *(MediaPad[^;]+|SpringBoard) Build/Huawei' + device_replacement: '$1' + brand_replacement: 'Huawei' + model_replacement: '$1' + - regex: '; *([^;]+) Build/Huawei' + device_replacement: '$1' + brand_replacement: 'Huawei' + model_replacement: '$1' + - regex: '; *([Uu])([89]\d{3}) Build' + device_replacement: '$1$2' + brand_replacement: 'Huawei' + model_replacement: 'U$2' + - regex: '; *(?:Ideos |IDEOS )(S7) Build' + device_replacement: 'Huawei Ideos$1' + brand_replacement: 'Huawei' + model_replacement: 'Ideos$1' + - regex: '; *(?:Ideos |IDEOS )([^;/]+\s*|\s*)Build' + device_replacement: 'Huawei Ideos$1' + brand_replacement: 'Huawei' + model_replacement: 'Ideos$1' + - regex: '; *(Orange Daytona|Pulse|Pulse Mini|Vodafone 858|C8500|C8600|C8650|C8660) Build' + device_replacement: 'Huawei $1' + brand_replacement: 'Huawei' + model_replacement: '$1' + + ######### + # HTC + # @ref: http://www.htc.com/www/products/ + # @ref: http://en.wikipedia.org/wiki/List_of_HTC_phones + ######### + + - regex: '; *HTC[ _]([^;]+); Windows Phone' + device_replacement: 'HTC $1' + brand_replacement: 'HTC' + model_replacement: '$1' + + # Android HTC with Version Number matcher + # ; HTC_0P3Z11/1.12.161.3 Build + # ;HTC_A3335 V2.38.841.1 Build + - regex: '; *(?:HTC[ _/])+([^ _/]+)(?:[/\\]1\.0 | V|/| +)\d+\.\d[\d\.]*(?: *Build|\))' + device_replacement: 'HTC $1' + brand_replacement: 'HTC' + model_replacement: '$1' + - regex: '; *(?:HTC[ _/])+([^ _/]+)(?:[ _/]([^ _/]+))?(?:[/\\]1\.0 | V|/| +)\d+\.\d[\d\.]*(?: *Build|\))' + device_replacement: 'HTC $1 $2' + brand_replacement: 'HTC' + model_replacement: '$1 $2' + - regex: '; *(?:HTC[ _/])+([^ _/]+)(?:[ _/]([^ _/]+)(?:[ _/]([^ _/]+))?)?(?:[/\\]1\.0 | V|/| +)\d+\.\d[\d\.]*(?: *Build|\))' + device_replacement: 'HTC $1 $2 $3' + brand_replacement: 'HTC' + model_replacement: '$1 $2 $3' + - regex: '; *(?:HTC[ _/])+([^ _/]+)(?:[ _/]([^ _/]+)(?:[ _/]([^ _/]+)(?:[ _/]([^ _/]+))?)?)?(?:[/\\]1\.0 | V|/| +)\d+\.\d[\d\.]*(?: *Build|\))' + device_replacement: 'HTC $1 $2 $3 $4' + brand_replacement: 'HTC' + model_replacement: '$1 $2 $3 $4' + + # Android HTC without Version Number matcher + - regex: '; *(?:(?:HTC|htc)(?:_blocked)*[ _/])+([^ _/;]+)(?: *Build|[;\)]| - )' + device_replacement: 'HTC $1' + brand_replacement: 'HTC' + model_replacement: '$1' + - regex: '; *(?:(?:HTC|htc)(?:_blocked)*[ _/])+([^ _/]+)(?:[ _/]([^ _/;\)]+))?(?: *Build|[;\)]| - )' + device_replacement: 'HTC $1 $2' + brand_replacement: 'HTC' + model_replacement: '$1 $2' + - regex: '; *(?:(?:HTC|htc)(?:_blocked)*[ _/])+([^ _/]+)(?:[ _/]([^ _/]+)(?:[ _/]([^ _/;\)]+))?)?(?: *Build|[;\)]| - )' + device_replacement: 'HTC $1 $2 $3' + brand_replacement: 'HTC' + model_replacement: '$1 $2 $3' + - regex: '; *(?:(?:HTC|htc)(?:_blocked)*[ _/])+([^ _/]+)(?:[ _/]([^ _/]+)(?:[ _/]([^ _/]+)(?:[ _/]([^ /;]+))?)?)?(?: *Build|[;\)]| - )' + device_replacement: 'HTC $1 $2 $3 $4' + brand_replacement: 'HTC' + model_replacement: '$1 $2 $3 $4' + + # HTC Streaming Player + - regex: 'HTC Streaming Player [^\/]*/[^\/]*/ htc_([^/]+) /' + device_replacement: 'HTC $1' + brand_replacement: 'HTC' + model_replacement: '$1' + # general matcher for anything else + - regex: '(?:[;,] *|^)(?:htccn_chs-)?HTC[ _-]?([^;]+?)(?: *Build|clay|Android|-?Mozilla| Opera| Profile| UNTRUSTED|[;/\(\)]|$)' + regex_flag: 'i' + device_replacement: 'HTC $1' + brand_replacement: 'HTC' + model_replacement: '$1' + # Android matchers without HTC + - regex: '; *(A6277|ADR6200|ADR6300|ADR6350|ADR6400[A-Z]*|ADR6425[A-Z]*|APX515CKT|ARIA|Desire[^_ ]*|Dream|EndeavorU|Eris|Evo|Flyer|HD2|Hero|HERO200|Hero CDMA|HTL21|Incredible|Inspire[A-Z0-9]*|Legend|Liberty|Nexus ?(?:One|HD2)|One|One S C2|One[ _]?(?:S|V|X\+?)\w*|PC36100|PG06100|PG86100|S31HT|Sensation|Wildfire)(?: Build|[/;\(\)])' + regex_flag: 'i' + device_replacement: 'HTC $1' + brand_replacement: 'HTC' + model_replacement: '$1' + - regex: '; *(ADR6200|ADR6400L|ADR6425LVW|Amaze|DesireS?|EndeavorU|Eris|EVO|Evo\d[A-Z]+|HD2|IncredibleS?|Inspire[A-Z0-9]*|Inspire[A-Z0-9]*|Sensation[A-Z0-9]*|Wildfire)[ _-](.+?)(?:[/;\)]|Build|MIUI|1\.0)' + regex_flag: 'i' + device_replacement: 'HTC $1 $2' + brand_replacement: 'HTC' + model_replacement: '$1 $2' + + ######### + # Hyundai + # @ref: http://www.hyundaitechnologies.com + ######### + - regex: '; *HYUNDAI (T\d[^/]*) Build' + device_replacement: 'Hyundai $1' + brand_replacement: 'Hyundai' + model_replacement: '$1' + - regex: '; *HYUNDAI ([^;/]+) Build' + device_replacement: 'Hyundai $1' + brand_replacement: 'Hyundai' + model_replacement: '$1' + # X900? http://www.amazon.com/Hyundai-X900-Retina-Android-Bluetooth/dp/B00AO07H3O + - regex: '; *(X700|Hold X|MB-6900) Build' + device_replacement: 'Hyundai $1' + brand_replacement: 'Hyundai' + model_replacement: '$1' + + ######### + # iBall + # @ref: http://www.iball.co.in/Category/Mobiles/22 + ######### + - regex: '; *(?:iBall[ _\-])?(Andi)[ _]?(\d[^;/]*) Build' + regex_flag: 'i' + device_replacement: '$1 $2' + brand_replacement: 'iBall' + model_replacement: '$1 $2' + - regex: '; *(IBall)(?:[ _]([^;/]+)|) Build' + regex_flag: 'i' + device_replacement: '$1 $2' + brand_replacement: 'iBall' + model_replacement: '$2' + + ######### + # IconBIT + # @ref: http://www.iconbit.com/catalog/tablets/ + ######### + - regex: '; *(NT-\d+[^ ;/]*|Net[Tt]AB [^;/]+|Mercury [A-Z]+|iconBIT)(?: S/N:[^;/]+)? Build' + device_replacement: '$1' + brand_replacement: 'IconBIT' + model_replacement: '$1' + + ######### + # IMO + # @ref: http://www.ponselimo.com/ + ######### + - regex: '; *(IMO)[ _]([^;/]+) Build' + regex_flag: 'i' + device_replacement: '$1 $2' + brand_replacement: 'IMO' + model_replacement: '$2' + + ######### + # i-mobile + # @ref: http://www.i-mobilephone.com/ + ######### + - regex: '; *i-?mobile[ _]([^/]+) Build/' + regex_flag: 'i' + device_replacement: 'i-mobile $1' + brand_replacement: 'imobile' + model_replacement: '$1' + - regex: '; *(i-(?:style|note)[^/]*) Build/' + regex_flag: 'i' + device_replacement: 'i-mobile $1' + brand_replacement: 'imobile' + model_replacement: '$1' + + ######### + # Impression + # @ref: http://impression.ua/planshetnye-kompyutery + ######### + - regex: '; *(ImPAD) ?(\d+(?:.)*) Build' + device_replacement: '$1 $2' + brand_replacement: 'Impression' + model_replacement: '$1 $2' + + ######### + # Infinix + # @ref: http://www.infinixmobility.com/index.html + ######### + - regex: '; *(Infinix)[ _]([^;/]+) Build' + device_replacement: '$1 $2' + brand_replacement: 'Infinix' + model_replacement: '$2' + + ######### + # Informer + # @ref: ?? + ######### + - regex: '; *(Informer)[ \-]([^;/]+) Build' + device_replacement: '$1 $2' + brand_replacement: 'Informer' + model_replacement: '$2' + + ######### + # Intenso + # @ref: http://www.intenso.de + # @models: 7":TAB 714,TAB 724;8":TAB 814,TAB 824;10":TAB 1004 + ######### + - regex: '; *(TAB) ?([78][12]4) Build' + device_replacement: 'Intenso $1' + brand_replacement: 'Intenso' + model_replacement: '$1 $2' + + ######### + # Intex + # @ref: http://intexmobile.in/index.aspx + # @note: Zync also offers a "Cloud Z5" device + ######### + # smartphones + - regex: '; *(?:Intex[ _])?(AQUA|Aqua)([ _\.\-])([^;/]+) *(?:Build|;)' + device_replacement: '$1$2$3' + brand_replacement: 'Intex' + model_replacement: '$1 $3' + # matches "INTEX CLOUD X1" + - regex: '; *(?:INTEX|Intex)(?:[_ ]([^\ _;/]+))(?:[_ ]([^\ _;/]+))? *(?:Build|;)' + device_replacement: '$1 $2' + brand_replacement: 'Intex' + model_replacement: '$1 $2' + # tablets + - regex: '; *([iI]Buddy)[ _]?(Connect)(?:_|\?_| )?([^;/]*) *(?:Build|;)' + device_replacement: '$1 $2 $3' + brand_replacement: 'Intex' + model_replacement: 'iBuddy $2 $3' + - regex: '; *(I-Buddy)[ _]([^;/]+) *(?:Build|;)' + device_replacement: '$1 $2' + brand_replacement: 'Intex' + model_replacement: 'iBuddy $2' + + ######### + # iOCEAN + # @ref: http://www.iocean.cc/ + ######### + - regex: '; *(iOCEAN) ([^/]+) Build' + regex_flag: 'i' + device_replacement: '$1 $2' + brand_replacement: 'iOCEAN' + model_replacement: '$2' + + ######### + # i.onik + # @ref: http://www.i-onik.de/ + ######### + - regex: '; *(TP\d+(?:\.\d+)?\-\d[^;/]+) Build' + device_replacement: 'ionik $1' + brand_replacement: 'ionik' + model_replacement: '$1' + + ######### + # IRU.ru + # @ref: http://www.iru.ru/catalog/soho/planetable/ + ######### + - regex: '; *(M702pro) Build' + device_replacement: '$1' + brand_replacement: 'Iru' + model_replacement: '$1' + + ######### + # Ivio + # @ref: http://www.ivio.com/mobile.php + # @models: DG80,DG20,DE38,DE88,MD70 + ######### + - regex: '; *(DE88Plus|MD70) Build' + device_replacement: '$1' + brand_replacement: 'Ivio' + model_replacement: '$1' + - regex: '; *IVIO[_\-]([^;/]+) Build' + device_replacement: '$1' + brand_replacement: 'Ivio' + model_replacement: '$1' + + ######### + # Jaytech + # @ref: http://www.jay-tech.de/jaytech/servlet/frontend/ + ######### + - regex: '; *(TPC-\d+|JAY-TECH) Build' + device_replacement: '$1' + brand_replacement: 'Jaytech' + model_replacement: '$1' + + ######### + # Jiayu + # @ref: http://www.ejiayu.com/en/Product.html + ######### + - regex: '; *(JY-[^;/]+|G[234]S?) Build' + device_replacement: '$1' + brand_replacement: 'Jiayu' + model_replacement: '$1' + + ######### + # JXD + # @ref: http://www.jxd.hk/ + ######### + - regex: '; *(JXD)[ _\-]([^;/]+) Build' + device_replacement: '$1 $2' + brand_replacement: 'JXD' + model_replacement: '$2' + + ######### + # Karbonn + # @ref: http://www.karbonnmobiles.com/products_tablet.php + ######### + - regex: '; *Karbonn[ _]?([^;/]+) *(?:Build|;)' + regex_flag: 'i' + device_replacement: '$1' + brand_replacement: 'Karbonn' + model_replacement: '$1' + - regex: '; *([^;]+) Build/Karbonn' + device_replacement: '$1' + brand_replacement: 'Karbonn' + model_replacement: '$1' + - regex: '; *(A11|A39|A37|A34|ST8|ST10|ST7|Smart Tab3|Smart Tab2|Titanium S\d) +Build' + device_replacement: '$1' + brand_replacement: 'Karbonn' + model_replacement: '$1' + + ######### + # KDDI (Operator Branded Device) + # @ref: http://www.ipentec.com/document/document.aspx?page=android-useragent + ######### + - regex: '; *(IS01|IS03|IS05|IS\d{2}SH) Build' + device_replacement: '$1' + brand_replacement: 'Sharp' + model_replacement: '$1' + - regex: '; *(IS04) Build' + device_replacement: '$1' + brand_replacement: 'Regza' + model_replacement: '$1' + - regex: '; *(IS06|IS\d{2}PT) Build' + device_replacement: '$1' + brand_replacement: 'Pantech' + model_replacement: '$1' + - regex: '; *(IS11S) Build' + device_replacement: '$1' + brand_replacement: 'SonyEricsson' + model_replacement: 'Xperia Acro' + - regex: '; *(IS11CA) Build' + device_replacement: '$1' + brand_replacement: 'Casio' + model_replacement: 'GzOne $1' + - regex: '; *(IS11LG) Build' + device_replacement: '$1' + brand_replacement: 'LG' + model_replacement: 'Optimus X' + - regex: '; *(IS11N) Build' + device_replacement: '$1' + brand_replacement: 'Medias' + model_replacement: '$1' + - regex: '; *(IS11PT) Build' + device_replacement: '$1' + brand_replacement: 'Pantech' + model_replacement: 'MIRACH' + - regex: '; *(IS12F) Build' + device_replacement: '$1' + brand_replacement: 'Fujitsu' + model_replacement: 'Arrows ES' + # @ref: https://ja.wikipedia.org/wiki/IS12M + - regex: '; *(IS12M) Build' + device_replacement: '$1' + brand_replacement: 'Motorola' + model_replacement: 'XT909' + - regex: '; *(IS12S) Build' + device_replacement: '$1' + brand_replacement: 'SonyEricsson' + model_replacement: 'Xperia Acro HD' + - regex: '; *(ISW11F) Build' + device_replacement: '$1' + brand_replacement: 'Fujitsu' + model_replacement: 'Arrowz Z' + - regex: '; *(ISW11HT) Build' + device_replacement: '$1' + brand_replacement: 'HTC' + model_replacement: 'EVO' + - regex: '; *(ISW11K) Build' + device_replacement: '$1' + brand_replacement: 'Kyocera' + model_replacement: 'DIGNO' + - regex: '; *(ISW11M) Build' + device_replacement: '$1' + brand_replacement: 'Motorola' + model_replacement: 'Photon' + - regex: '; *(ISW11SC) Build' + device_replacement: '$1' + brand_replacement: 'Samsung' + model_replacement: 'GALAXY S II WiMAX' + - regex: '; *(ISW12HT) Build' + device_replacement: '$1' + brand_replacement: 'HTC' + model_replacement: 'EVO 3D' + - regex: '; *(ISW13HT) Build' + device_replacement: '$1' + brand_replacement: 'HTC' + model_replacement: 'J' + - regex: '; *(ISW?[0-9]{2}[A-Z]{0,2}) Build' + device_replacement: '$1' + brand_replacement: 'KDDI' + model_replacement: '$1' + - regex: '; *(INFOBAR [^;/]+) Build' + device_replacement: '$1' + brand_replacement: 'KDDI' + model_replacement: '$1' + + ######### + # Kingcom + # @ref: http://www.e-kingcom.com + ######### + - regex: '; *(JOYPAD|Joypad)[ _]([^;/]+) Build/' + device_replacement: '$1 $2' + brand_replacement: 'Kingcom' + model_replacement: '$1 $2' + + ######### + # Kobo + # @ref: https://en.wikipedia.org/wiki/Kobo_Inc. + # @ref: http://www.kobo.com/devices#tablets + ######### + - regex: '; *(Vox|VOX|Arc|K080) Build/' + regex_flag: 'i' + device_replacement: '$1' + brand_replacement: 'Kobo' + model_replacement: '$1' + - regex: '\b(Kobo Touch)\b' + device_replacement: '$1' + brand_replacement: 'Kobo' + model_replacement: '$1' + + ######### + # K-Touch + # @ref: ?? + ######### + - regex: '; *(K-Touch)[ _]([^;/]+) Build' + regex_flag: 'i' + device_replacement: '$1 $2' + brand_replacement: 'Ktouch' + model_replacement: '$2' + + ######### + # KT Tech + # @ref: http://www.kttech.co.kr + ######### + - regex: '; *((?:EV|KM)-S\d+[A-Z]?) Build' + regex_flag: 'i' + device_replacement: '$1' + brand_replacement: 'KTtech' + model_replacement: '$1' + + ######### + # Kyocera + # @ref: http://www.android.com/devices/?country=all&m=kyocera + ######### + - regex: '; *(Zio|Hydro|Torque|Event|EVENT|Echo|Milano|Rise|URBANO PROGRESSO|WX04K|WX06K|WX10K|KYL21|101K|C5[12]\d{2}) Build/' + device_replacement: '$1' + brand_replacement: 'Kyocera' + model_replacement: '$1' + + ######### + # Lava + # @ref: http://www.lavamobiles.com/ + ######### + - regex: '; *(?:LAVA[ _])?IRIS[ _\-]?([^/;\)]+) *(?:;|\)|Build)' + regex_flag: 'i' + device_replacement: 'Iris $1' + brand_replacement: 'Lava' + model_replacement: 'Iris $1' + - regex: '; *LAVA[ _]([^;/]+) Build' + device_replacement: '$1' + brand_replacement: 'Lava' + model_replacement: '$1' + + ######### + # Lemon + # @ref: http://www.lemonmobiles.com/products.php?type=1 + ######### + - regex: '; *(?:(Aspire A1)|(?:LEMON|Lemon)[ _]([^;/]+))_? Build' + device_replacement: 'Lemon $1$2' + brand_replacement: 'Lemon' + model_replacement: '$1$2' + + ######### + # Lenco + # @ref: http://www.lenco.com/c/tablets/ + ######### + - regex: '; *(TAB-1012) Build/' + device_replacement: 'Lenco $1' + brand_replacement: 'Lenco' + model_replacement: '$1' + - regex: '; Lenco ([^;/]+) Build/' + device_replacement: 'Lenco $1' + brand_replacement: 'Lenco' + model_replacement: '$1' + + ######### + # Lenovo + # @ref: http://support.lenovo.com/en_GB/downloads/default.page?# + ######### + - regex: '; *(A1_07|A2107A-H|S2005A-H|S1-37AH0) Build' + device_replacement: '$1' + brand_replacement: 'Lenovo' + model_replacement: '$1' + - regex: '; *(Idea[Tp]ab)[ _]([^;/]+);? Build' + device_replacement: 'Lenovo $1 $2' + brand_replacement: 'Lenovo' + model_replacement: '$1 $2' + - regex: '; *(Idea(?:Tab|pad)) ?([^;/]+) Build' + device_replacement: 'Lenovo $1 $2' + brand_replacement: 'Lenovo' + model_replacement: '$1 $2' + - regex: '; *(ThinkPad) ?(Tablet) Build/' + device_replacement: 'Lenovo $1 $2' + brand_replacement: 'Lenovo' + model_replacement: '$1 $2' + - regex: '; *(?:LNV-)?(?:=?[Ll]enovo[ _\-]?|LENOVO[ _])+(.+?)(?:Build|[;/\)])' + device_replacement: 'Lenovo $1' + brand_replacement: 'Lenovo' + model_replacement: '$1' + - regex: '[;,] (?:Vodafone )?(SmartTab) ?(II) ?(\d+) Build/' + device_replacement: 'Lenovo $1 $2 $3' + brand_replacement: 'Lenovo' + model_replacement: '$1 $2 $3' + - regex: '; *(?:Ideapad )?K1 Build/' + device_replacement: 'Lenovo Ideapad K1' + brand_replacement: 'Lenovo' + model_replacement: 'Ideapad K1' + - regex: '; *(3GC101|3GW10[01]|A390) Build/' + device_replacement: '$1' + brand_replacement: 'Lenovo' + model_replacement: '$1' + - regex: '\b(?:Lenovo|LENOVO)+[ _\-]?([^,;:/ ]+)' + device_replacement: 'Lenovo $1' + brand_replacement: 'Lenovo' + model_replacement: '$1' + + ######### + # Lexibook + # @ref: http://www.lexibook.com/fr + ######### + - regex: '; *(MFC\d+)[A-Z]{2}([^;,/]*),? Build' + device_replacement: '$1$2' + brand_replacement: 'Lexibook' + model_replacement: '$1$2' + + ######### + # LG + # @ref: http://www.lg.com/uk/mobile + ######### + - regex: '; *(E[34][0-9]{2}|LS[6-8][0-9]{2}|VS[6-9][0-9]+[^;/]+|Nexus [45]|GT540f?|Optimus (?:2X|G|4X HD)|OptimusX4HD) *(?:Build|;)' + device_replacement: '$1' + brand_replacement: 'LG' + model_replacement: '$1' + - regex: '[;:] *(L-\d+[A-Z]|LGL\d+[A-Z]?)(?:/V\d+)? *(?:Build|[;\)])' + device_replacement: '$1' + brand_replacement: 'LG' + model_replacement: '$1' + - regex: '; *(LG-)([A-Z]{1,2}\d{2,}[^,;/\)\(]*?)(?:Build| V\d+|[,;/\)\(]|$)' + device_replacement: '$1$2' + brand_replacement: 'LG' + model_replacement: '$2' + - regex: '; *(LG[ \-]|LG)([^;/]+)[;/]? Build' + device_replacement: '$1$2' + brand_replacement: 'LG' + model_replacement: '$2' + - regex: '^(LG)-([^;/]+)/ Mozilla/.*; Android' + device_replacement: '$1 $2' + brand_replacement: 'LG' + model_replacement: '$2' + + ######### + # Malata + # @ref: http://www.malata.com/en/products.aspx?classid=680 + ######### + - regex: '; *((?:SMB|smb)[^;/]+) Build/' + device_replacement: '$1' + brand_replacement: 'Malata' + model_replacement: '$1' + - regex: '; *(?:Malata|MALATA) ([^;/]+) Build/' + device_replacement: '$1' + brand_replacement: 'Malata' + model_replacement: '$1' + + ######### + # Manta + # @ref: http://www.manta.com.pl/en + ######### + - regex: '; *(MS[45][0-9]{3}|MID0[568][NS]?|MID[1-9]|MID[78]0[1-9]|MID970[1-9]|MID100[1-9]) Build/' + device_replacement: '$1' + brand_replacement: 'Manta' + model_replacement: '$1' + + ######### + # Match + # @ref: http://www.match.net.cn/products.asp + ######### + - regex: '; *(M1052|M806|M9000|M9100|M9701|MID100|MID120|MID125|MID130|MID135|MID140|MID701|MID710|MID713|MID727|MID728|MID731|MID732|MID733|MID735|MID736|MID737|MID760|MID800|MID810|MID820|MID830|MID833|MID835|MID860|MID900|MID930|MID933|MID960|MID980) Build/' + device_replacement: '$1' + brand_replacement: 'Match' + model_replacement: '$1' + + ######### + # Maxx + # @ref: http://www.maxxmobile.in/ + # @models: Maxx MSD7-Play, Maxx MX245+ Trance, Maxx AX8 Race, Maxx MSD7 3G- AX50, Maxx Genx Droid 7 - AX40, Maxx AX5 Duo, + # Maxx AX3 Duo, Maxx AX3, Maxx AX8 Note II (Note 2), Maxx AX8 Note I, Maxx AX8, Maxx AX5 Plus, Maxx MSD7 Smarty, + # Maxx AX9Z Race, + # Maxx MT150, Maxx MQ601, Maxx M2020, Maxx Sleek MX463neo, Maxx MX525, Maxx MX192-Tune, Maxx Genx Droid 7 AX353, + # @note: Need more User-Agents!!! + ######### + - regex: '; *(GenxDroid7|MSD7.*|AX\d.*|Tab 701|Tab 722) Build/' + device_replacement: 'Maxx $1' + brand_replacement: 'Maxx' + model_replacement: '$1' + + ######### + # Mediacom + # @ref: http://www.mediacomeurope.it/ + ######### + - regex: '; *(M-PP[^;/]+|PhonePad ?\d{2,}[^;/]+) Build' + device_replacement: 'Mediacom $1' + brand_replacement: 'Mediacom' + model_replacement: '$1' + - regex: '; *(M-MP[^;/]+|SmartPad ?\d{2,}[^;/]+) Build' + device_replacement: 'Mediacom $1' + brand_replacement: 'Mediacom' + model_replacement: '$1' + + ######### + # Medion + # @ref: http://www.medion.com/en/ + ######### + - regex: '; *(?:MD_)?LIFETAB[ _]([^;/]+) Build' + regex_flag: 'i' + device_replacement: 'Medion Lifetab $1' + brand_replacement: 'Medion' + model_replacement: 'Lifetab $1' + - regex: '; *MEDION ([^;/]+) Build' + device_replacement: 'Medion $1' + brand_replacement: 'Medion' + model_replacement: '$1' + + ######### + # Meizu + # @ref: http://www.meizu.com + ######### + - regex: '; *(M030|M031|M035|M040|M065|m9) Build' + device_replacement: 'Meizu $1' + brand_replacement: 'Meizu' + model_replacement: '$1' + - regex: '; *(?:meizu_|MEIZU )(.+?) *(?:Build|[;\)])' + device_replacement: 'Meizu $1' + brand_replacement: 'Meizu' + model_replacement: '$1' + + ######### + # Micromax + # @ref: http://www.micromaxinfo.com + ######### + - regex: '; *(?:Micromax[ _](A111|A240)|(A111|A240)) Build' + regex_flag: 'i' + device_replacement: 'Micromax $1$2' + brand_replacement: 'Micromax' + model_replacement: '$1$2' + - regex: '; *Micromax[ _](A\d{2,3}[^;/]*) Build' + regex_flag: 'i' + device_replacement: 'Micromax $1' + brand_replacement: 'Micromax' + model_replacement: '$1' + # be carefull here with Acer e.g. A500 + - regex: '; *(A\d{2}|A[12]\d{2}|A90S|A110Q) Build' + regex_flag: 'i' + device_replacement: 'Micromax $1' + brand_replacement: 'Micromax' + model_replacement: '$1' + - regex: '; *Micromax[ _](P\d{3}[^;/]*) Build' + regex_flag: 'i' + device_replacement: 'Micromax $1' + brand_replacement: 'Micromax' + model_replacement: '$1' + - regex: '; *(P\d{3}|P\d{3}\(Funbook\)) Build' + regex_flag: 'i' + device_replacement: 'Micromax $1' + brand_replacement: 'Micromax' + model_replacement: '$1' + + ######### + # Mito + # @ref: http://new.mitomobile.com/ + ######### + - regex: '; *(MITO)[ _\-]?([^;/]+) Build' + regex_flag: 'i' + device_replacement: '$1 $2' + brand_replacement: 'Mito' + model_replacement: '$2' + + ######### + # Mobistel + # @ref: http://www.mobistel.com/ + ######### + - regex: '; *(Cynus)[ _](F5|T\d|.+?) *(?:Build|[;/\)])' + regex_flag: 'i' + device_replacement: '$1 $2' + brand_replacement: 'Mobistel' + model_replacement: '$1 $2' + + ######### + # Modecom + # @ref: http://www.modecom.eu/tablets/portal/ + ######### + - regex: '; *(MODECOM )?(FreeTab) ?([^;/]+) Build' + regex_flag: 'i' + device_replacement: '$1$2 $3' + brand_replacement: 'Modecom' + model_replacement: '$2 $3' + - regex: '; *(MODECOM )([^;/]+) Build' + regex_flag: 'i' + device_replacement: '$1 $2' + brand_replacement: 'Modecom' + model_replacement: '$2' + + ######### + # Motorola + # @ref: http://www.motorola.com/us/shop-all-mobile-phones/ + ######### + - regex: '; *(MZ\d{3}\+?|MZ\d{3} 4G|Xoom|XOOM[^;/]*) Build' + device_replacement: 'Motorola $1' + brand_replacement: 'Motorola' + model_replacement: '$1' + - regex: '; *(Milestone )(XT[^;/]*) Build' + device_replacement: 'Motorola $1$2' + brand_replacement: 'Motorola' + model_replacement: '$2' + - regex: '; *(Motoroi ?x|Droid X|DROIDX) Build' + regex_flag: 'i' + device_replacement: 'Motorola $1' + brand_replacement: 'Motorola' + model_replacement: 'DROID X' + - regex: '; *(Droid[^;/]*|DROID[^;/]*|Milestone[^;/]*|Photon|Triumph|Devour|Titanium) Build' + device_replacement: 'Motorola $1' + brand_replacement: 'Motorola' + model_replacement: '$1' + - regex: '; *(A555|A85[34][^;/]*|A95[356]|ME[58]\d{2}\+?|ME600|ME632|ME722|MB\d{3}\+?|MT680|MT710|MT870|MT887|MT917|WX435|WX453|WX44[25]|XT\d{3,4}[A-Z\+]*|CL[iI]Q|CL[iI]Q XT) Build' + device_replacement: '$1' + brand_replacement: 'Motorola' + model_replacement: '$1' + - regex: '; *(Motorola MOT-|Motorola[ _\-]|MOT\-?)([^;/]+) Build' + device_replacement: '$1$2' + brand_replacement: 'Motorola' + model_replacement: '$2' + - regex: '; *(Moto[_ ]?|MOT\-)([^;/]+) Build' + device_replacement: '$1$2' + brand_replacement: 'Motorola' + model_replacement: '$2' + + ######### + # MpMan + # @ref: http://www.mpmaneurope.com + ######### + - regex: '; *((?:MP[DQ]C|MPG\d{1,4}|MP\d{3,4}|MID(?:(?:10[234]|114|43|7[247]|8[24]|7)C|8[01]1))[^;/]*) Build' + device_replacement: '$1' + brand_replacement: 'Mpman' + model_replacement: '$1' + + ######### + # MSI + # @ref: http://www.msi.com/product/windpad/ + ######### + - regex: '; *(?:MSI[ _])?(Primo\d+|Enjoy[ _\-][^;/]+) Build' + regex_flag: 'i' + device_replacement: '$1' + brand_replacement: 'Msi' + model_replacement: '$1' + + ######### + # Multilaser + # http://www.multilaser.com.br/listagem_produtos.php?cat=5 + ######### + - regex: '; *Multilaser[ _]([^;/]+) Build' + device_replacement: '$1' + brand_replacement: 'Multilaser' + model_replacement: '$1' + + ######### + # MyPhone + # @ref: http://myphone.com.ph/ + ######### + - regex: '; *(My)[_]?(Pad)[ _]([^;/]+) Build' + device_replacement: '$1$2 $3' + brand_replacement: 'MyPhone' + model_replacement: '$1$2 $3' + - regex: '; *(My)\|?(Phone)[ _]([^;/]+) Build' + device_replacement: '$1$2 $3' + brand_replacement: 'MyPhone' + model_replacement: '$3' + - regex: '; *(A\d+)[ _](Duo)? Build' + regex_flag: 'i' + device_replacement: '$1 $2' + brand_replacement: 'MyPhone' + model_replacement: '$1 $2' + + ######### + # Mytab + # @ref: http://www.mytab.eu/en/category/mytab-products/ + ######### + - regex: '; *(myTab[^;/]*) Build' + device_replacement: '$1' + brand_replacement: 'Mytab' + model_replacement: '$1' + + ######### + # Nabi + # @ref: https://www.nabitablet.com + ######### + - regex: '; *(NABI2?-)([^;/]+) Build/' + device_replacement: '$1$2' + brand_replacement: 'Nabi' + model_replacement: '$2' + + ######### + # Nec Medias + # @ref: http://www.n-keitai.com/ + ######### + - regex: '; *(N-\d+[CDE]) Build/' + device_replacement: '$1' + brand_replacement: 'Nec' + model_replacement: '$1' + - regex: '; ?(NEC-)(.*) Build/' + device_replacement: '$1$2' + brand_replacement: 'Nec' + model_replacement: '$2' + - regex: '; *(LT-NA7) Build/' + device_replacement: '$1' + brand_replacement: 'Nec' + model_replacement: 'Lifetouch Note' + + ######### + # Nextbook + # @ref: http://nextbookusa.com + ######### + - regex: '; *(NXM\d+[A-z0-9_]*|Next\d[A-z0-9_ \-]*|NEXT\d[A-z0-9_ \-]*|Nextbook [A-z0-9_ ]*|DATAM803HC|M805)(?: Build|[\);])' + device_replacement: '$1' + brand_replacement: 'Nextbook' + model_replacement: '$1' + + ######### + # Nokia + # @ref: http://www.nokia.com + ######### + - regex: '; *(Nokia)([ _\-]*)([^;/]*) Build' + regex_flag: 'i' + device_replacement: '$1$2$3' + brand_replacement: 'Nokia' + model_replacement: '$3' + + ######### + # Nook + # @ref: + # TODO nook browser/1.0 + ######### + - regex: '; *(Nook ?|Barnes & Noble Nook |BN )([^;/]+) Build' + device_replacement: '$1$2' + brand_replacement: 'Nook' + model_replacement: '$2' + - regex: '; *(NOOK )?(BNRV200|BNRV200A|BNTV250|BNTV250A|BNTV400|BNTV600|LogicPD Zoom2) Build' + device_replacement: '$1$2' + brand_replacement: 'Nook' + model_replacement: '$2' + - regex: '; Build/(Nook)' + device_replacement: '$1' + brand_replacement: 'Nook' + model_replacement: 'Tablet' + + ######### + # Olivetti + # @ref: http://www.olivetti.de/EN/Page/t02/view_html?idp=348 + ######### + - regex: '; *(OP110|OliPad[^;/]+) Build' + device_replacement: 'Olivetti $1' + brand_replacement: 'Olivetti' + model_replacement: '$1' + + ######### + # Omega + # @ref: http://omega-technology.eu/en/produkty/346/tablets + # @note: MID tablets might get matched by CobyKyros first + # @models: (T107|MID(?:700[2-5]|7031|7108|7132|750[02]|8001|8500|9001|971[12]) + ######### + - regex: '; *OMEGA[ _\-](MID[^;/]+) Build' + device_replacement: 'Omega $1' + brand_replacement: 'Omega' + model_replacement: '$1' + - regex: '^(MID7500|MID\d+) Mozilla/5\.0 \(iPad;' + device_replacement: 'Omega $1' + brand_replacement: 'Omega' + model_replacement: '$1' + + ######### + # OpenPeak + # @ref: https://support.google.com/googleplay/answer/1727131?hl=en + ######### + - regex: '; *((?:CIUS|cius)[^;/]*) Build' + device_replacement: 'Openpeak $1' + brand_replacement: 'Openpeak' + model_replacement: '$1' + + ######### + # Oppo + # @ref: http://en.oppo.com/products/ + ######### + - regex: '; *(Find ?(?:5|7a)|R8[012]\d{1,2}|T703\d{0,1}|U70\d{1,2}T?|X90\d{1,2}) Build' + device_replacement: 'Oppo $1' + brand_replacement: 'Oppo' + model_replacement: '$1' + - regex: '; *OPPO ?([^;/]+) Build/' + device_replacement: 'Oppo $1' + brand_replacement: 'Oppo' + model_replacement: '$1' + + ######### + # Odys + # @ref: http://odys.de + ######### + - regex: '; *(?:Odys\-|ODYS\-|ODYS )([^;/]+) Build' + device_replacement: 'Odys $1' + brand_replacement: 'Odys' + model_replacement: '$1' + - regex: '; *(SELECT) ?(7) Build' + device_replacement: 'Odys $1 $2' + brand_replacement: 'Odys' + model_replacement: '$1 $2' + - regex: '; *(PEDI)_(PLUS)_(W) Build' + device_replacement: 'Odys $1 $2 $3' + brand_replacement: 'Odys' + model_replacement: '$1 $2 $3' + # Weltbild - Tablet PC 4 = Cat Phoenix = Odys Tablet PC 4? + - regex: '; *(AEON|BRAVIO|FUSION|FUSION2IN1|Genio|EOS10|IEOS[^;/]*|IRON|Loox|LOOX|LOOX Plus|Motion|NOON|NOON_PRO|NEXT|OPOS|PEDI[^;/]*|PRIME[^;/]*|STUDYTAB|TABLO|Tablet-PC-4|UNO_X8|XELIO[^;/]*|Xelio ?\d+ ?[Pp]ro|XENO10|XPRESS PRO) Build' + device_replacement: 'Odys $1' + brand_replacement: 'Odys' + model_replacement: '$1' + + ######### + # Orion + # @ref: http://www.orion.ua/en/products/computer-products/tablet-pcs.html + ######### + - regex: '; *(TP-\d+) Build/' + device_replacement: 'Orion $1' + brand_replacement: 'Orion' + model_replacement: '$1' + + ######### + # PackardBell + # @ref: http://www.packardbell.com/pb/en/AE/content/productgroup/tablets + ######### + - regex: '; *(G100W?) Build/' + device_replacement: 'PackardBell $1' + brand_replacement: 'PackardBell' + model_replacement: '$1' + + ######### + # Panasonic + # @ref: http://panasonic.jp/mobile/ + # @models: T11, T21, T31, P11, P51, Eluga Power, Eluga DL1 + # @models: (tab) Toughpad FZ-A1, Toughpad JT-B1 + ######### + - regex: '; *(Panasonic)[_ ]([^;/]+) Build' + device_replacement: '$1 $2' + brand_replacement: '$1' + model_replacement: '$2' + # Toughpad + - regex: '; *(FZ-A1B|JT-B1) Build' + device_replacement: 'Panasonic $1' + brand_replacement: 'Panasonic' + model_replacement: '$1' + # Eluga Power + - regex: '; *(dL1|DL1) Build' + device_replacement: 'Panasonic $1' + brand_replacement: 'Panasonic' + model_replacement: '$1' + + ######### + # Pantech + # @href: http://www.pantech.co.kr/en/prod/prodList.do?gbrand=PANTECH + # @href: http://www.pantech.co.kr/en/prod/prodList.do?gbrand=VEGA + # @models: ADR8995, ADR910L, ADR930VW, C790, CDM8992, CDM8999, IS06, IS11PT, P2000, P2020, P2030, P4100, P5000, P6010, P6020, P6030, P7000, P7040, P8000, P8010, P9020, P9050, P9060, P9070, P9090, PT001, PT002, PT003, TXT8040, TXT8045, VEGA PTL21 + ######### + - regex: '; *(SKY[ _])?(IM\-[AT]\d{3}[^;/]+).* Build/' + device_replacement: 'Pantech $1$2' + brand_replacement: 'Pantech' + model_replacement: '$1$2' + - regex: '; *((?:ADR8995|ADR910L|ADR930L|ADR930VW|PTL21|P8000)(?: 4G)?) Build/' + device_replacement: '$1' + brand_replacement: 'Pantech' + model_replacement: '$1' + - regex: '; *Pantech([^;/]+).* Build/' + device_replacement: 'Pantech $1' + brand_replacement: 'Pantech' + model_replacement: '$1' + + ######### + # Papayre + # @ref: http://grammata.es/ + ######### + - regex: '; *(papyre)[ _\-]([^;/]+) Build/' + regex_flag: 'i' + device_replacement: '$1 $2' + brand_replacement: 'Papyre' + model_replacement: '$2' + + ######### + # Pearl + # @ref: http://www.pearl.de/c-1540.shtml + ######### + - regex: '; *(?:Touchlet )?(X10\.[^;/]+) Build/' + device_replacement: 'Pearl $1' + brand_replacement: 'Pearl' + model_replacement: '$1' + + ######### + # Phicomm + # @ref: http://www.phicomm.com.cn/ + ######### + - regex: '; PHICOMM (i800) Build/' + device_replacement: 'Phicomm $1' + brand_replacement: 'Phicomm' + model_replacement: '$1' + - regex: '; PHICOMM ([^;/]+) Build/' + device_replacement: 'Phicomm $1' + brand_replacement: 'Phicomm' + model_replacement: '$1' + - regex: '; *(FWS\d{3}[^;/]+) Build/' + device_replacement: 'Phicomm $1' + brand_replacement: 'Phicomm' + model_replacement: '$1' + + ######### + # Philips + # @ref: http://www.support.philips.com/support/catalog/products.jsp?_dyncharset=UTF-8&country=&categoryid=MOBILE_PHONES_SMART_SU_CN_CARE&userLanguage=en&navCount=2&groupId=PC_PRODUCTS_AND_PHONES_GR_CN_CARE&catalogType=&navAction=push&userCountry=cn&title=Smartphones&cateId=MOBILE_PHONES_CA_CN_CARE + # @TODO: Philips Tablets User-Agents missing! + # @ref: http://www.support.philips.com/support/catalog/products.jsp?_dyncharset=UTF-8&country=&categoryid=ENTERTAINMENT_TABLETS_SU_CN_CARE&userLanguage=en&navCount=0&groupId=&catalogType=&navAction=push&userCountry=cn&title=Entertainment+Tablets&cateId=TABLETS_CA_CN_CARE + ######### + # @note: this a best guess according to available philips models. Need more User-Agents + - regex: '; *(D633|D822|D833|T539|T939|V726|W335|W336|W337|W3568|W536|W5510|W626|W632|W6350|W6360|W6500|W732|W736|W737|W7376|W820|W832|W8355|W8500|W8510|W930) Build' + device_replacement: '$1' + brand_replacement: 'Philips' + model_replacement: '$1' + - regex: '; *(?:Philips|PHILIPS)[ _]([^;/]+) Build' + device_replacement: 'Philips $1' + brand_replacement: 'Philips' + model_replacement: '$1' + + ######### + # Pipo + # @ref: http://www.pipo.cn/En/ + ######### + - regex: 'Android 4\..*; *(M[12356789]|U[12368]|S[123])\ ?(pro)? Build' + device_replacement: 'Pipo $1$2' + brand_replacement: 'Pipo' + model_replacement: '$1$2' + + ######### + # Ployer + # @ref: http://en.ployer.cn/ + ######### + - regex: '; *(MOMO[^;/]+) Build' + device_replacement: '$1' + brand_replacement: 'Ployer' + model_replacement: '$1' + + ######### + # Polaroid/ Acho + # @ref: http://polaroidstore.com/store/start.asp?category_id=382&category_id2=0&order=title&filter1=&filter2=&filter3=&view=all + ######### + - regex: '; *(?:Polaroid[ _])?((?:MIDC\d{3,}|PMID\d{2,}|PTAB\d{3,})[^;/]*)(\/[^;/]*)? Build/' + device_replacement: '$1' + brand_replacement: 'Polaroid' + model_replacement: '$1' + - regex: '; *(?:Polaroid )(Tablet) Build/' + device_replacement: '$1' + brand_replacement: 'Polaroid' + model_replacement: '$1' + + ######### + # Pomp + # @ref: http://pompmobileshop.com/ + ######### + #~ TODO + - regex: '; *(POMP)[ _\-](.+?) *(?:Build|[;/\)])' + device_replacement: '$1 $2' + brand_replacement: 'Pomp' + model_replacement: '$2' + + ######### + # Positivo + # @ref: http://www.positivoinformatica.com.br/www/pessoal/tablet-ypy/ + ######### + - regex: '; *(TB07STA|TB10STA|TB07FTA|TB10FTA) Build/' + device_replacement: '$1' + brand_replacement: 'Positivo' + model_replacement: '$1' + - regex: '; *(?:Positivo )?((?:YPY|Ypy)[^;/]+) Build/' + device_replacement: '$1' + brand_replacement: 'Positivo' + model_replacement: '$1' + + ######### + # POV + # @ref: http://www.pointofview-online.com/default2.php + # @TODO: Smartphone Models MOB-3515, MOB-5045-B missing + ######### + - regex: '; *(MOB-[^;/]+) Build/' + device_replacement: '$1' + brand_replacement: 'POV' + model_replacement: '$1' + - regex: '; *POV[ _\-]([^;/]+) Build/' + device_replacement: 'POV $1' + brand_replacement: 'POV' + model_replacement: '$1' + - regex: '; *((?:TAB-PLAYTAB|TAB-PROTAB|PROTAB|PlayTabPro|Mobii[ _\-]|TAB-P)[^;/]*) Build/' + device_replacement: 'POV $1' + brand_replacement: 'POV' + model_replacement: '$1' + + ######### + # Prestigio + # @ref: http://www.prestigio.com/catalogue/MultiPhones + # @ref: http://www.prestigio.com/catalogue/MultiPads + ######### + - regex: '; *(?:Prestigio )?((?:PAP|PMP)\d[^;/]+) Build/' + device_replacement: 'Prestigio $1' + brand_replacement: 'Prestigio' + model_replacement: '$1' + + ######### + # Proscan + # @ref: http://www.proscanvideo.com/products-search.asp?itemClass=TABLET&itemnmbr= + ######### + - regex: '; *(PLT[0-9]{4}.*) Build/' + device_replacement: '$1' + brand_replacement: 'Proscan' + model_replacement: '$1' + + ######### + # QMobile + # @ref: http://www.qmobile.com.pk/ + ######### + - regex: '; *(A2|A5|A8|A900)_?(Classic)? Build' + device_replacement: '$1 $2' + brand_replacement: 'Qmobile' + model_replacement: '$1 $2' + - regex: '; *(Q[Mm]obile)_([^_]+)_([^_]+) Build' + device_replacement: 'Qmobile $2 $3' + brand_replacement: 'Qmobile' + model_replacement: '$2 $3' + - regex: '; *(Q\-?[Mm]obile)[_ ](A[^;/]+) Build' + device_replacement: 'Qmobile $2' + brand_replacement: 'Qmobile' + model_replacement: '$2' + + ######### + # Qmobilevn + # @ref: http://qmobile.vn/san-pham.html + ######### + - regex: '; *(Q\-Smart)[ _]([^;/]+) Build/' + device_replacement: '$1 $2' + brand_replacement: 'Qmobilevn' + model_replacement: '$2' + - regex: '; *(Q\-?[Mm]obile)[ _\-](S[^;/]+) Build/' + device_replacement: '$1 $2' + brand_replacement: 'Qmobilevn' + model_replacement: '$2' + + ######### + # Quanta + # @ref: ? + ######### + - regex: '; *(TA1013) Build' + device_replacement: '$1' + brand_replacement: 'Quanta' + model_replacement: '$1' + + ######### + # Rockchip + # @ref: http://www.rock-chips.com/a/cn/product/index.html + # @note: manufacturer sells chipsets - I assume that these UAs are dev-boards + ######### + - regex: '; *(RK\d+),? Build/' + device_replacement: '$1' + brand_replacement: 'Rockchip' + model_replacement: '$1' + - regex: ' Build/(RK\d+)' + device_replacement: '$1' + brand_replacement: 'Rockchip' + model_replacement: '$1' + + ######### + # Samsung Android Devices + # @ref: http://www.samsung.com/us/mobile/cell-phones/all-products + ######### + - regex: '; *(SAMSUNG |Samsung )?((?:Galaxy (?:Note II|S\d)|GT-I9082|GT-I9205|GT-N7\d{3}|SM-N9005)[^;/]*)\/?[^;/]* Build/' + device_replacement: 'Samsung $1$2' + brand_replacement: 'Samsung' + model_replacement: '$2' + - regex: '; *(Google )?(Nexus [Ss](?: 4G)?) Build/' + device_replacement: 'Samsung $1$2' + brand_replacement: 'Samsung' + model_replacement: '$2' + - regex: '; *(SAMSUNG |Samsung )([^\/]*)\/[^ ]* Build/' + device_replacement: 'Samsung $2' + brand_replacement: 'Samsung' + model_replacement: '$2' + - regex: '; *(Galaxy(?: Ace| Nexus| S ?II+|Nexus S| with MCR 1.2| Mini Plus 4G)?) Build/' + device_replacement: 'Samsung $1' + brand_replacement: 'Samsung' + model_replacement: '$1' + - regex: '; *(SAMSUNG[ _\-] *)+([^;/]+) Build' + device_replacement: 'Samsung $2' + brand_replacement: 'Samsung' + model_replacement: '$2' + - regex: '; *(SAMSUNG-)?(GT\-[BINPS]\d{4}[^\/]*)(\/[^ ]*) Build' + device_replacement: 'Samsung $1$2$3' + brand_replacement: 'Samsung' + model_replacement: '$2' + - regex: '(?:; *|^)((?:GT\-[BIiNPS]\d{4}|I9\d{2}0[A-Za-z\+]?\b)[^;/\)]*?)(?:Build|Linux|MIUI|[;/\)])' + device_replacement: 'Samsung $1' + brand_replacement: 'Samsung' + model_replacement: '$1' + - regex: '; (SAMSUNG-)([A-Za-z0-9\-]+).* Build/' + device_replacement: 'Samsung $1$2' + brand_replacement: 'Samsung' + model_replacement: '$2' + - regex: '; *((?:SCH|SGH|SHV|SHW|SPH|SC|SM)\-[A-Za-z0-9 ]+)(/?[^ ]*)? Build' + device_replacement: 'Samsung $1' + brand_replacement: 'Samsung' + model_replacement: '$1' + - regex: ' ((?:SCH)\-[A-Za-z0-9 ]+)(/?[^ ]*)? Build' + device_replacement: 'Samsung $1' + brand_replacement: 'Samsung' + model_replacement: '$1' + - regex: '; *(Behold ?(?:2|II)|YP\-G[^;/]+|EK-GC100|SCL21|I9300) Build' + device_replacement: 'Samsung $1' + brand_replacement: 'Samsung' + model_replacement: '$1' + + ######### + # Sharp + # @ref: http://www.sharp-phone.com/en/index.html + # @ref: http://www.android.com/devices/?country=all&m=sharp + ######### + - regex: '; *(SH\-?\d\d[^;/]+|SBM\d[^;/]+) Build' + device_replacement: '$1' + brand_replacement: 'Sharp' + model_replacement: '$1' + - regex: '; *(SHARP[ -])([^;/]+) Build' + device_replacement: '$1$2' + brand_replacement: 'Sharp' + model_replacement: '$2' + + ######### + # Simvalley + # @ref: http://www.simvalley-mobile.de/ + ######### + - regex: '; *(SPX[_\-]\d[^;/]*) Build/' + device_replacement: '$1' + brand_replacement: 'Simvalley' + model_replacement: '$1' + - regex: '; *(SX7\-PEARL\.GmbH) Build/' + device_replacement: '$1' + brand_replacement: 'Simvalley' + model_replacement: '$1' + - regex: '; *(SP[T]?\-\d{2}[^;/]*) Build/' + device_replacement: '$1' + brand_replacement: 'Simvalley' + model_replacement: '$1' + + ######### + # SK Telesys + # @ref: http://www.sk-w.com/phone/phone_list.jsp + # @ref: http://www.android.com/devices/?country=all&m=sk-telesys + ######### + - regex: '; *(SK\-.*) Build/' + device_replacement: '$1' + brand_replacement: 'SKtelesys' + model_replacement: '$1' + + ######### + # Skytex + # @ref: http://skytex.com/android + ######### + - regex: '; *(?:SKYTEX|SX)-([^;/]+) Build' + device_replacement: '$1' + brand_replacement: 'Skytex' + model_replacement: '$1' + - regex: '; *(IMAGINE [^;/]+) Build' + device_replacement: '$1' + brand_replacement: 'Skytex' + model_replacement: '$1' + + ######### + # SmartQ + # @ref: http://en.smartdevices.com.cn/Products/ + # @models: Z8, X7, U7H, U7, T30, T20, Ten3, V5-II, T7-3G, SmartQ5, K7, S7, Q8, T19, Ten2, Ten, R10, T7, R7, V5, V7, SmartQ7 + ######### + - regex: '; *(SmartQ) ?([^;/]+) Build/' + device_replacement: '$1 $2' + brand_replacement: '$1' + model_replacement: '$2' + + ######### + # Smartbitt + # @ref: http://www.smartbitt.com/ + # @missing: SBT Useragents + ######### + - regex: '; *(WF7C|WF10C|SBT[^;/]+) Build' + device_replacement: '$1' + brand_replacement: 'Smartbitt' + model_replacement: '$1' + + ######### + # Softbank (Operator Branded Devices) + # @ref: http://www.ipentec.com/document/document.aspx?page=android-useragent + ######### + - regex: '; *(SBM(?:003SH|005SH|006SH|007SH|102SH)) Build' + device_replacement: '$1' + brand_replacement: 'Sharp' + model_replacement: '$1' + - regex: '; *(003P|101P|101P11C|102P) Build' + device_replacement: '$1' + brand_replacement: 'Panasonic' + model_replacement: '$1' + - regex: '; *(00\dZ) Build/' + device_replacement: '$1' + brand_replacement: 'ZTE' + model_replacement: '$1' + - regex: '; HTC(X06HT) Build' + device_replacement: '$1' + brand_replacement: 'HTC' + model_replacement: '$1' + - regex: '; *(001HT|X06HT) Build' + device_replacement: '$1' + brand_replacement: 'HTC' + model_replacement: '$1' + - regex: '; *(201M) Build' + device_replacement: '$1' + brand_replacement: 'Motorola' + model_replacement: 'XT902' + + ######### + # Trekstor + # @ref: http://www.trekstor.co.uk/surftabs-en.html + # @note: Must come before SonyEricsson + ######### + - regex: '; *(ST\d{4}.*)Build/ST' + device_replacement: 'Trekstor $1' + brand_replacement: 'Trekstor' + model_replacement: '$1' + - regex: '; *(ST\d{4}.*) Build/' + device_replacement: 'Trekstor $1' + brand_replacement: 'Trekstor' + model_replacement: '$1' + + ######### + # SonyEricsson + # @note: Must come before nokia since they also use symbian + # @ref: http://www.android.com/devices/?country=all&m=sony-ericssons + # @TODO: type! + ######### + # android matchers + - regex: '; *(Sony ?Ericsson ?)([^;/]+) Build' + device_replacement: '$1$2' + brand_replacement: 'SonyEricsson' + model_replacement: '$2' + - regex: '; *((?:SK|ST|E|X|LT|MK|MT|WT)\d{2}[a-z0-9]*(?:-o)?|R800i|U20i) Build' + device_replacement: '$1' + brand_replacement: 'SonyEricsson' + model_replacement: '$1' + # TODO X\d+ is wrong + - regex: '; *(Xperia (?:A8|Arc|Acro|Active|Live with Walkman|Mini|Neo|Play|Pro|Ray|X\d+)[^;/]*) Build' + regex_flag: 'i' + device_replacement: '$1' + brand_replacement: 'SonyEricsson' + model_replacement: '$1' + + ######### + # Sony + # @ref: http://www.sonymobile.co.jp/index.html + # @ref: http://www.sonymobile.com/global-en/products/phones/ + # @ref: http://www.sony.jp/tablet/ + ######### + - regex: '; Sony (Tablet[^;/]+) Build' + device_replacement: 'Sony $1' + brand_replacement: 'Sony' + model_replacement: '$1' + - regex: '; Sony ([^;/]+) Build' + device_replacement: 'Sony $1' + brand_replacement: 'Sony' + model_replacement: '$1' + - regex: '; *(Sony)([A-Za-z0-9\-]+) Build' + device_replacement: '$1 $2' + brand_replacement: '$1' + model_replacement: '$2' + - regex: '; *(Xperia [^;/]+) Build' + device_replacement: '$1' + brand_replacement: 'Sony' + model_replacement: '$1' + - regex: '; *(C(?:1[0-9]|2[0-9]|53|55|6[0-9])[0-9]{2}|D[25]\d{3}|D6[56]\d{2}) Build' + device_replacement: '$1' + brand_replacement: 'Sony' + model_replacement: '$1' + - regex: '; *(SGP\d{3}|SGPT\d{2}) Build' + device_replacement: '$1' + brand_replacement: 'Sony' + model_replacement: '$1' + - regex: '; *(NW-Z1000Series) Build' + device_replacement: '$1' + brand_replacement: 'Sony' + model_replacement: '$1' + + ########## + # Sony PlayStation + # @ref: http://playstation.com + # The Vita spoofs the Kindle + ########## + - regex: 'PLAYSTATION 3' + device_replacement: 'PlayStation 3' + brand_replacement: 'Sony' + model_replacement: 'PlayStation 3' + - regex: '(PlayStation (?:Portable|Vita|\d+))' + device_replacement: '$1' + brand_replacement: 'Sony' + model_replacement: '$1' + + ######### + # Spice + # @ref: http://www.spicemobilephones.co.in/ + ######### + - regex: '; *((?:CSL_Spice|Spice|SPICE|CSL)[ _\-]?)?([Mm][Ii])([ _\-])?(\d{3}[^;/]*) Build/' + device_replacement: '$1$2$3$4' + brand_replacement: 'Spice' + model_replacement: 'Mi$4' + + ######### + # Sprint (Operator Branded Devices) + # @ref: + ######### + - regex: '; *(Sprint )(.+?) *(?:Build|[;/])' + device_replacement: '$1$2' + brand_replacement: 'Sprint' + model_replacement: '$2' + - regex: '\b(Sprint)[: ]([^;,/ ]+)' + device_replacement: '$1$2' + brand_replacement: 'Sprint' + model_replacement: '$2' + + ######### + # Tagi + # @ref: ?? + ######### + - regex: '; *(TAGI[ ]?)(MID) ?([^;/]+) Build/' + device_replacement: '$1$2$3' + brand_replacement: 'Tagi' + model_replacement: '$2$3' + + ######### + # Tecmobile + # @ref: http://www.tecmobile.com/ + ######### + - regex: '; *(Oyster500|Opal 800) Build' + device_replacement: 'Tecmobile $1' + brand_replacement: 'Tecmobile' + model_replacement: '$1' + + ######### + # Tecno + # @ref: www.tecno-mobile.com/‎ + ######### + - regex: '; *(TECNO[ _])([^;/]+) Build/' + device_replacement: '$1$2' + brand_replacement: 'Tecno' + model_replacement: '$2' + + ######### + # Telechips, Techvision evaluation boards + # @ref: + ######### + - regex: '; *Android for (Telechips|Techvision) ([^ ]+) ' + regex_flag: 'i' + device_replacement: '$1 $2' + brand_replacement: '$1' + model_replacement: '$2' + + ######### + # Telstra + # @ref: http://www.telstra.com.au/home-phone/thub-2/ + # @ref: https://support.google.com/googleplay/answer/1727131?hl=en + ######### + - regex: '; *(T-Hub2) Build/' + device_replacement: '$1' + brand_replacement: 'Telstra' + model_replacement: '$1' + + ######### + # Terra + # @ref: http://www.wortmann.de/ + ######### + - regex: '; *(PAD) ?(100[12]) Build/' + device_replacement: 'Terra $1$2' + brand_replacement: 'Terra' + model_replacement: '$1$2' + + ######### + # Texet + # @ref: http://www.texet.ru/tablet/ + ######### + - regex: '; *(T[BM]-\d{3}[^;/]+) Build/' + device_replacement: '$1' + brand_replacement: 'Texet' + model_replacement: '$1' + + ######### + # Thalia + # @ref: http://www.thalia.de/shop/tolino-shine-ereader/show/ + ######### + - regex: '; *(tolino [^;/]+) Build' + device_replacement: '$1' + brand_replacement: 'Thalia' + model_replacement: '$1' + - regex: '; *Build/.* (TOLINO_BROWSER)' + device_replacement: '$1' + brand_replacement: 'Thalia' + model_replacement: 'Tolino Shine' + + ######### + # Thl + # @ref: http://en.thl.com.cn/Mobile + # @ref: http://thlmobilestore.com + ######### + - regex: '; *(?:CJ[ -])?(ThL|THL)[ -]([^;/]+) Build/' + device_replacement: '$1 $2' + brand_replacement: 'Thl' + model_replacement: '$2' + - regex: '; *(T100|T200|T5|W100|W200|W8s) Build/' + device_replacement: '$1' + brand_replacement: 'Thl' + model_replacement: '$1' + + ######### + # T-Mobile (Operator Branded Devices) + ######### + # @ref: https://en.wikipedia.org/wiki/HTC_Hero + - regex: '; *(T-Mobile[ _]G2[ _]Touch) Build' + device_replacement: '$1' + brand_replacement: 'HTC' + model_replacement: 'Hero' + # @ref: https://en.wikipedia.org/wiki/HTC_Desire_Z + - regex: '; *(T-Mobile[ _]G2) Build' + device_replacement: '$1' + brand_replacement: 'HTC' + model_replacement: 'Desire Z' + - regex: '; *(T-Mobile myTouch Q) Build' + device_replacement: '$1' + brand_replacement: 'Huawei' + model_replacement: 'U8730' + - regex: '; *(T-Mobile myTouch) Build' + device_replacement: '$1' + brand_replacement: 'Huawei' + model_replacement: 'U8680' + - regex: '; *(T-Mobile_Espresso) Build' + device_replacement: '$1' + brand_replacement: 'HTC' + model_replacement: 'Espresso' + - regex: '; *(T-Mobile G1) Build' + device_replacement: '$1' + brand_replacement: 'HTC' + model_replacement: 'Dream' + - regex: '\b(T-Mobile ?)?(myTouch)[ _]?([34]G)[ _]?([^\/]*) (?:Mozilla|Build)' + device_replacement: '$1$2 $3 $4' + brand_replacement: 'HTC' + model_replacement: '$2 $3 $4' + - regex: '\b(T-Mobile)_([^_]+)_(.*) Build' + device_replacement: '$1 $2 $3' + brand_replacement: 'Tmobile' + model_replacement: '$2 $3' + - regex: '\b(T-Mobile)[_ ]?(.*?)Build' + device_replacement: '$1 $2' + brand_replacement: 'Tmobile' + model_replacement: '$2' + + ######### + # Tomtec + # @ref: http://www.tom-tec.eu/pages/tablets.php + ######### + - regex: ' (ATP[0-9]{4}) Build' + device_replacement: '$1' + brand_replacement: 'Tomtec' + model_replacement: '$1' + + ######### + # Tooky + # @ref: http://www.tookymobile.com/ + ######### + - regex: ' *(TOOKY)[ _\-]([^;/]+) ?(?:Build|;)' + regex_flag: 'i' + device_replacement: '$1 $2' + brand_replacement: 'Tooky' + model_replacement: '$2' + + ######### + # Toshiba + # @ref: http://www.toshiba.co.jp/ + # @missing: LT170, Thrive 7, TOSHIBA STB10 + ######### + - regex: '\b(TOSHIBA_AC_AND_AZ|TOSHIBA_FOLIO_AND_A|FOLIO_AND_A)' + device_replacement: '$1' + brand_replacement: 'Toshiba' + model_replacement: 'Folio 100' + - regex: '; *([Ff]olio ?100) Build/' + device_replacement: '$1' + brand_replacement: 'Toshiba' + model_replacement: 'Folio 100' + - regex: '; *(AT[0-9]{2,3}(?:\-A|LE\-A|PE\-A|SE|a)?|AT7-A|AT1S0|Hikari-iFrame/WDPF-[^;/]+|THRiVE|Thrive) Build/' + device_replacement: 'Toshiba $1' + brand_replacement: 'Toshiba' + model_replacement: '$1' + + ######### + # Touchmate + # @ref: http://touchmatepc.com/new/ + ######### + - regex: '; *(TM-MID\d+[^;/]+|TOUCHMATE|MID-750) Build' + device_replacement: '$1' + brand_replacement: 'Touchmate' + model_replacement: '$1' + # @todo: needs verification user-agents missing + - regex: '; *(TM-SM\d+[^;/]+) Build' + device_replacement: '$1' + brand_replacement: 'Touchmate' + model_replacement: '$1' + + ######### + # Treq + # @ref: http://www.treq.co.id/product + ######### + - regex: '; *(A10 [Bb]asic2?) Build/' + device_replacement: '$1' + brand_replacement: 'Treq' + model_replacement: '$1' + - regex: '; *(TREQ[ _\-])([^;/]+) Build' + regex_flag: 'i' + device_replacement: '$1$2' + brand_replacement: 'Treq' + model_replacement: '$2' + + ######### + # Umeox + # @ref: http://umeox.com/ + # @models: A936|A603|X-5|X-3 + ######### + # @todo: guessed markers + - regex: '; *(X-?5|X-?3) Build/' + device_replacement: '$1' + brand_replacement: 'Umeox' + model_replacement: '$1' + # @todo: guessed markers + - regex: '; *(A502\+?|A936|A603|X1|X2) Build/' + device_replacement: '$1' + brand_replacement: 'Umeox' + model_replacement: '$1' + + ######### + # Versus + # @ref: http://versusuk.com/support.html + ######### + - regex: '(TOUCH(?:TAB|PAD).+?) Build/' + regex_flag: 'i' + device_replacement: 'Versus $1' + brand_replacement: 'Versus' + model_replacement: '$1' + + ######### + # Vertu + # @ref: http://www.vertu.com/ + ######### + - regex: '(VERTU) ([^;/]+) Build/' + device_replacement: '$1 $2' + brand_replacement: 'Vertu' + model_replacement: '$2' + + ######### + # Videocon + # @ref: http://www.videoconmobiles.com + ######### + - regex: '; *(Videocon)[ _\-]([^;/]+) *(?:Build|;)' + device_replacement: '$1 $2' + brand_replacement: 'Videocon' + model_replacement: '$2' + - regex: ' (VT\d{2}[A-Za-z]*) Build' + device_replacement: '$1' + brand_replacement: 'Videocon' + model_replacement: '$1' + + ######### + # Viewsonic + # @ref: http://viewsonic.com + ######### + - regex: '; *((?:ViewPad|ViewPhone|VSD)[^;/]+) Build/' + device_replacement: '$1' + brand_replacement: 'Viewsonic' + model_replacement: '$1' + - regex: '; *(ViewSonic-)([^;/]+) Build/' + device_replacement: '$1$2' + brand_replacement: 'Viewsonic' + model_replacement: '$2' + - regex: '; *(GTablet.*) Build/' + device_replacement: '$1' + brand_replacement: 'Viewsonic' + model_replacement: '$1' + + ######### + # vivo + # @ref: http://vivo.cn/ + ######### + - regex: '; *([Vv]ivo)[ _]([^;/]+) Build' + device_replacement: '$1 $2' + brand_replacement: 'vivo' + model_replacement: '$2' + + ######### + # Vodafone (Operator Branded Devices) + # @ref: ?? + ######### + - regex: '(Vodafone) (.*) Build/' + device_replacement: '$1 $2' + brand_replacement: '$1' + model_replacement: '$2' + + ######### + # Walton + # @ref: http://www.waltonbd.com/ + ######### + - regex: '; *(?:Walton[ _\-])?(Primo[ _\-][^;/]+) Build' + regex_flag: 'i' + device_replacement: 'Walton $1' + brand_replacement: 'Walton' + model_replacement: '$1' + + ######### + # Wiko + # @ref: http://fr.wikomobile.com/collection.php?s=Smartphones + ######### + - regex: '; *(?:WIKO[ \-])?(CINK\+?|BARRY|BLOOM|DARKFULL|DARKMOON|DARKNIGHT|DARKSIDE|FIZZ|HIGHWAY|IGGY|OZZY|RAINBOW|STAIRWAY|SUBLIM|WAX|CINK [^;/]+) Build/' + regex_flag: 'i' + device_replacement: 'Wiko $1' + brand_replacement: 'Wiko' + model_replacement: '$1' + + ######### + # WellcoM + # @ref: ?? + ######### + - regex: '; *WellcoM-([^;/]+) Build' + device_replacement: 'Wellcom $1' + brand_replacement: 'Wellcom' + model_replacement: '$1' + + ########## + # WeTab + # @ref: http://wetab.mobi/ + ########## + - regex: '(?:(WeTab)-Browser|; (wetab) Build)' + device_replacement: '$1' + brand_replacement: 'WeTab' + model_replacement: 'WeTab' + + ######### + # Wolfgang + # @ref: http://wolfgangmobile.com/ + ######### + - regex: '; *(AT-AS[^;/]+) Build' + device_replacement: 'Wolfgang $1' + brand_replacement: 'Wolfgang' + model_replacement: '$1' + + ######### + # Woxter + # @ref: http://www.woxter.es/es-es/categories/index + ######### + - regex: '; *(?:Woxter|Wxt) ([^;/]+) Build' + device_replacement: 'Woxter $1' + brand_replacement: 'Woxter' + model_replacement: '$1' + + ######### + # Yarvik Zania + # @ref: http://yarvik.com + ######### + - regex: '; *(?:Xenta |Luna )?(TAB[234][0-9]{2}|TAB0[78]-\d{3}|TAB0?9-\d{3}|TAB1[03]-\d{3}|SMP\d{2}-\d{3}) Build/' + device_replacement: 'Yarvik $1' + brand_replacement: 'Yarvik' + model_replacement: '$1' + + ######### + # Yifang + # @note: Needs to be at the very last as manufacturer builds for other brands. + # @ref: http://www.yifangdigital.com/ + # @models: M1010, M1011, M1007, M1008, M1005, M899, M899LP, M909, M8000, + # M8001, M8002, M8003, M849, M815, M816, M819, M805, M878, M780LPW, + # M778, M7000, M7000AD, M7000NBD, M7001, M7002, M7002KBD, M777, M767, + # M789, M799, M769, M757, M755, M753, M752, M739, M729, M723, M712, M727 + ######### + - regex: '; *([A-Z]{2,4})(M\d{3,}[A-Z]{2})([^;\)\/]*)(?: Build|[;\)])' + device_replacement: 'Yifang $1$2$3' + brand_replacement: 'Yifang' + model_replacement: '$2' + + ######### + # XiaoMi + # @ref: http://www.xiaomi.com/event/buyphone + ######### + - regex: '; *((MI|HM|MI-ONE|Redmi)[ -](NOTE |Note )?[^;/]*) Build/' + device_replacement: 'XiaoMi $1' + brand_replacement: 'XiaoMi' + model_replacement: '$1' + + ######### + # Xolo + # @ref: http://www.xolo.in/ + ######### + - regex: '; *XOLO[ _]([^;/]*tab.*) Build' + regex_flag: 'i' + device_replacement: 'Xolo $1' + brand_replacement: 'Xolo' + model_replacement: '$1' + - regex: '; *XOLO[ _]([^;/]+) Build' + regex_flag: 'i' + device_replacement: 'Xolo $1' + brand_replacement: 'Xolo' + model_replacement: '$1' + - regex: '; *(q\d0{2,3}[a-z]?) Build' + regex_flag: 'i' + device_replacement: 'Xolo $1' + brand_replacement: 'Xolo' + model_replacement: '$1' + + ######### + # Xoro + # @ref: http://www.xoro.de/produkte/ + ######### + - regex: '; *(PAD ?[79]\d+[^;/]*|TelePAD\d+[^;/]) Build' + device_replacement: 'Xoro $1' + brand_replacement: 'Xoro' + model_replacement: '$1' + + ######### + # Zopo + # @ref: http://www.zopomobiles.com/products.html + ######### + - regex: '; *(?:(?:ZOPO|Zopo)[ _]([^;/]+)|(ZP ?(?:\d{2}[^;/]+|C2))|(C[2379])) Build' + device_replacement: '$1$2$3' + brand_replacement: 'Zopo' + model_replacement: '$1$2$3' + + ######### + # ZiiLabs + # @ref: http://www.ziilabs.com/products/platforms/androidreferencetablets.php + ######### + - regex: '; *(ZiiLABS) (Zii[^;/]*) Build' + device_replacement: '$1 $2' + brand_replacement: 'ZiiLabs' + model_replacement: '$2' + - regex: '; *(Zii)_([^;/]*) Build' + device_replacement: '$1 $2' + brand_replacement: 'ZiiLabs' + model_replacement: '$2' + + ######### + # ZTE + # @ref: http://www.ztedevices.com/ + ######### + - regex: '; *(ARIZONA|(?:ATLAS|Atlas) W|D930|Grand (?:[SX][^;]*|Era|Memo[^;]*)|JOE|(?:Kis|KIS)\b[^;]*|Libra|Light [^;]*|N8[056][01]|N850L|N8000|N9[15]\d{2}|N9810|NX501|Optik|(?:Vip )Racer[^;]*|RacerII|RACERII|San Francisco[^;]*|V9[AC]|V55|V881|Z[679][0-9]{2}[A-z]?) Build' + device_replacement: '$1' + brand_replacement: 'ZTE' + model_replacement: '$1' + - regex: '; *([A-Z]\d+)_USA_[^;]* Build' + device_replacement: '$1' + brand_replacement: 'ZTE' + model_replacement: '$1' + - regex: '; *(SmartTab\d+)[^;]* Build' + device_replacement: '$1' + brand_replacement: 'ZTE' + model_replacement: '$1' + - regex: '; *(?:Blade|BLADE|ZTE-BLADE)([^;/]*) Build' + device_replacement: 'ZTE Blade$1' + brand_replacement: 'ZTE' + model_replacement: 'Blade$1' + - regex: '; *(?:Skate|SKATE|ZTE-SKATE)([^;/]*) Build' + device_replacement: 'ZTE Skate$1' + brand_replacement: 'ZTE' + model_replacement: 'Skate$1' + - regex: '; *(Orange |Optimus )(Monte Carlo|San Francisco) Build' + device_replacement: '$1$2' + brand_replacement: 'ZTE' + model_replacement: '$1$2' + - regex: '; *(?:ZXY-ZTE_|ZTE\-U |ZTE[\- _]|ZTE-C[_ ])([^;/]+) Build' + device_replacement: 'ZTE $1' + brand_replacement: 'ZTE' + model_replacement: '$1' + # operator specific + - regex: '; (BASE) (lutea|Lutea 2|Tab[^;]*) Build' + device_replacement: '$1 $2' + brand_replacement: 'ZTE' + model_replacement: '$1 $2' + - regex: '; (Avea inTouch 2|soft stone|tmn smart a7|Movistar[ _]Link) Build' + regex_flag: 'i' + device_replacement: '$1' + brand_replacement: 'ZTE' + model_replacement: '$1' + - regex: '; *(vp9plus)\)' + device_replacement: '$1' + brand_replacement: 'ZTE' + model_replacement: '$1' + + ########## + # Zync + # @ref: http://www.zync.in/index.php/our-products/tablet-phablets + ########## + - regex: '; ?(Cloud[ _]Z5|z1000|Z99 2G|z99|z930|z999|z990|z909|Z919|z900) Build/' + device_replacement: '$1' + brand_replacement: 'Zync' + model_replacement: '$1' + + ########## + # Kindle + # @note: Needs to be after Sony Playstation Vita as this UA contains Silk/3.2 + # @ref: https://developer.amazon.com/sdk/fire/specifications.html + # @ref: http://amazonsilk.wordpress.com/useful-bits/silk-user-agent/ + ########## + - regex: '; ?(KFOT|Kindle Fire) Build\b' + device_replacement: 'Kindle Fire' + brand_replacement: 'Amazon' + model_replacement: 'Kindle Fire' + - regex: '; ?(KFOTE|Amazon Kindle Fire2) Build\b' + device_replacement: 'Kindle Fire 2' + brand_replacement: 'Amazon' + model_replacement: 'Kindle Fire 2' + - regex: '; ?(KFTT) Build\b' + device_replacement: 'Kindle Fire HD' + brand_replacement: 'Amazon' + model_replacement: 'Kindle Fire HD 7"' + - regex: '; ?(KFJWI) Build\b' + device_replacement: 'Kindle Fire HD 8.9" WiFi' + brand_replacement: 'Amazon' + model_replacement: 'Kindle Fire HD 8.9" WiFi' + - regex: '; ?(KFJWA) Build\b' + device_replacement: 'Kindle Fire HD 8.9" 4G' + brand_replacement: 'Amazon' + model_replacement: 'Kindle Fire HD 8.9" 4G' + - regex: '; ?(KFSOWI) Build\b' + device_replacement: 'Kindle Fire HD 7" WiFi' + brand_replacement: 'Amazon' + model_replacement: 'Kindle Fire HD 7" WiFi' + - regex: '; ?(KFTHWI) Build\b' + device_replacement: 'Kindle Fire HDX 7" WiFi' + brand_replacement: 'Amazon' + model_replacement: 'Kindle Fire HDX 7" WiFi' + - regex: '; ?(KFTHWA) Build\b' + device_replacement: 'Kindle Fire HDX 7" 4G' + brand_replacement: 'Amazon' + model_replacement: 'Kindle Fire HDX 7" 4G' + - regex: '; ?(KFAPWI) Build\b' + device_replacement: 'Kindle Fire HDX 8.9" WiFi' + brand_replacement: 'Amazon' + model_replacement: 'Kindle Fire HDX 8.9" WiFi' + - regex: '; ?(KFAPWA) Build\b' + device_replacement: 'Kindle Fire HDX 8.9" 4G' + brand_replacement: 'Amazon' + model_replacement: 'Kindle Fire HDX 8.9" 4G' + - regex: '; ?Amazon ([^;/]+) Build\b' + device_replacement: '$1' + brand_replacement: 'Amazon' + model_replacement: '$1' + - regex: '; ?(Kindle) Build\b' + device_replacement: 'Kindle' + brand_replacement: 'Amazon' + model_replacement: 'Kindle' + - regex: '; ?(Silk)/(\d+)\.(\d+)(?:\.([0-9\-]+))? Build\b' + device_replacement: 'Kindle Fire' + brand_replacement: 'Amazon' + model_replacement: 'Kindle Fire$2' + - regex: ' (Kindle)/(\d+\.\d+)' + device_replacement: 'Kindle' + brand_replacement: 'Amazon' + model_replacement: '$1 $2' + - regex: ' (Silk|Kindle)/(\d+)\.' + device_replacement: 'Kindle' + brand_replacement: 'Amazon' + model_replacement: 'Kindle' + + ######### + # Devices from chinese manufacturer(s) + # @note: identified by x-wap-profile http://218.249.47.94/Xianghe/.* + ######### + - regex: '(sprd)\-([^/]+)/' + device_replacement: '$1 $2' + brand_replacement: '$1' + model_replacement: '$2' + # @ref: http://eshinechina.en.alibaba.com/ + - regex: '; *(H\d{2}00\+?) Build' + device_replacement: '$1' + brand_replacement: 'Hero' + model_replacement: '$1' + - regex: '; *(iphone|iPhone5) Build/' + device_replacement: 'Xianghe $1' + brand_replacement: 'Xianghe' + model_replacement: '$1' + - regex: '; *(e\d{4}[a-z]?_?v\d+|v89_[^;/]+)[^;/]+ Build/' + device_replacement: 'Xianghe $1' + brand_replacement: 'Xianghe' + model_replacement: '$1' + + ######### + # Cellular + # @ref: + # @note: Operator branded devices + ######### + - regex: '\bUSCC[_\-]?([^ ;/\)]+)' + device_replacement: '$1' + brand_replacement: 'Cellular' + model_replacement: '$1' + + ###################################################################### + # Windows Phone Parsers + ###################################################################### + + ######### + # Alcatel Windows Phones + ######### + - regex: 'Windows Phone [^;]+; .*?IEMobile/[^;\)]+[;\)] ?(?:ARM; ?Touch; ?|Touch; ?)?(?:ALCATEL)[^;]*; *([^;,\)]+)' + device_replacement: 'Alcatel $1' + brand_replacement: 'Alcatel' + model_replacement: '$1' + + ######### + # Asus Windows Phones + ######### + #~ - regex: 'Windows Phone [^;]+; .*?IEMobile/[^;\)]+[;\)] ?(?:ARM; ?Touch; ?|Touch; ?|WpsLondonTest; ?)?(?:ASUS|Asus)[^;]*; *([^;,\)]+)' + - regex: 'Windows Phone [^;]+; .*?IEMobile/[^;\)]+[;\)] ?(?:ARM; ?Touch; ?|Touch; ?|WpsLondonTest; ?)?(?:ASUS|Asus)[^;]*; *([^;,\)]+)' + device_replacement: 'Asus $1' + brand_replacement: 'Asus' + model_replacement: '$1' + + ######### + # Dell Windows Phones + ######### + - regex: 'Windows Phone [^;]+; .*?IEMobile/[^;\)]+[;\)] ?(?:ARM; ?Touch; ?|Touch; ?)?(?:DELL|Dell)[^;]*; *([^;,\)]+)' + device_replacement: 'Dell $1' + brand_replacement: 'Dell' + model_replacement: '$1' + + ######### + # HTC Windows Phones + ######### + - regex: 'Windows Phone [^;]+; .*?IEMobile/[^;\)]+[;\)] ?(?:ARM; ?Touch; ?|Touch; ?|WpsLondonTest; ?)?(?:HTC|Htc|HTC_blocked[^;]*)[^;]*; *(?:HTC)?([^;,\)]+)' + device_replacement: 'HTC $1' + brand_replacement: 'HTC' + model_replacement: '$1' + + ######### + # Huawei Windows Phones + ######### + - regex: 'Windows Phone [^;]+; .*?IEMobile/[^;\)]+[;\)] ?(?:ARM; ?Touch; ?|Touch; ?)?(?:HUAWEI)[^;]*; *(?:HUAWEI )?([^;,\)]+)' + device_replacement: 'Huawei $1' + brand_replacement: 'Huawei' + model_replacement: '$1' + + ######### + # LG Windows Phones + ######### + - regex: 'Windows Phone [^;]+; .*?IEMobile/[^;\)]+[;\)] ?(?:ARM; ?Touch; ?|Touch; ?)?(?:LG|Lg)[^;]*; *(?:LG[ \-])?([^;,\)]+)' + device_replacement: 'LG $1' + brand_replacement: 'LG' + model_replacement: '$1' + + ######### + # Noka Windows Phones + ######### + - regex: 'Windows Phone [^;]+; .*?IEMobile/[^;\)]+[;\)] ?(?:ARM; ?Touch; ?|Touch; ?)?(?:NOKIA|Nokia)[^;]*; *(?:NOKIA ?|Nokia ?|LUMIA ?|[Ll]umia ?)*(\d{3,}[^;\)]*)' + device_replacement: 'Lumia $1' + brand_replacement: 'Nokia' + model_replacement: 'Lumia $1' + - regex: 'Windows Phone [^;]+; .*?IEMobile/[^;\)]+[;\)] ?(?:ARM; ?Touch; ?|Touch; ?)?(?:NOKIA|Nokia)[^;]*; *(RM-\d{3,})' + device_replacement: 'Nokia $1' + brand_replacement: 'Nokia' + model_replacement: '$1' + - regex: '(?:Windows Phone [^;]+; .*?IEMobile/[^;\)]+[;\)]|WPDesktop;) ?(?:ARM; ?Touch; ?|Touch; ?)?(?:NOKIA|Nokia)[^;]*; *(?:NOKIA ?|Nokia ?|LUMIA ?|[Ll]umia ?)*([^;\)]+)' + device_replacement: 'Nokia $1' + brand_replacement: 'Nokia' + model_replacement: '$1' + + ######### + # Microsoft Windows Phones + ######### + - regex: 'Windows Phone [^;]+; .*?IEMobile/[^;\)]+[;\)] ?(?:ARM; ?Touch; ?|Touch; ?)?(?:Microsoft(?: Corporation)?)[^;]*; *([^;,\)]+)' + device_replacement: 'Microsoft $1' + brand_replacement: 'Microsoft' + model_replacement: '$1' + + ######### + # Samsung Windows Phones + ######### + - regex: 'Windows Phone [^;]+; .*?IEMobile/[^;\)]+[;\)] ?(?:ARM; ?Touch; ?|Touch; ?|WpsLondonTest; ?)?(?:SAMSUNG)[^;]*; *(?:SAMSUNG )?([^;,\.\)]+)' + device_replacement: 'Samsung $1' + brand_replacement: 'Samsung' + model_replacement: '$1' + + ######### + # Toshiba Windows Phones + ######### + - regex: 'Windows Phone [^;]+; .*?IEMobile/[^;\)]+[;\)] ?(?:ARM; ?Touch; ?|Touch; ?|WpsLondonTest; ?)?(?:TOSHIBA|FujitsuToshibaMobileCommun)[^;]*; *([^;,\)]+)' + device_replacement: 'Toshiba $1' + brand_replacement: 'Toshiba' + model_replacement: '$1' + + ######### + # Generic Windows Phones + ######### + - regex: 'Windows Phone [^;]+; .*?IEMobile/[^;\)]+[;\)] ?(?:ARM; ?Touch; ?|Touch; ?|WpsLondonTest; ?)?([^;]+); *([^;,\)]+)' + device_replacement: '$1 $2' + brand_replacement: '$1' + model_replacement: '$2' + + ###################################################################### + # Other Devices Parser + ###################################################################### + + ######### + # Samsung Bada Phones + ######### + - regex: '(?:^|; )SAMSUNG\-([A-Za-z0-9\-]+).* Bada/' + device_replacement: 'Samsung $1' + brand_replacement: 'Samsung' + model_replacement: '$1' + + ######### + # Firefox OS + ######### + - regex: '\(Mobile; ALCATEL ?(One|ONE) ?(Touch|TOUCH) ?([^;/]+)(?:/[^;]+)?; rv:[^\)]+\) Gecko/[^\/]+ Firefox/' + device_replacement: 'Alcatel $1 $2 $3' + brand_replacement: 'Alcatel' + model_replacement: 'One Touch $3' + - regex: '\(Mobile; (?:ZTE([^;]+)|(OpenC)); rv:[^\)]+\) Gecko/[^\/]+ Firefox/' + device_replacement: 'ZTE $1$2' + brand_replacement: 'ZTE' + model_replacement: '$1$2' + + ########## + # NOKIA + # @note: NokiaN8-00 comes before iphone. Sometimes spoofs iphone + ########## + - regex: 'Nokia(N[0-9]+)([A-z_\-][A-z0-9_\-]*)' + device_replacement: 'Nokia $1' + brand_replacement: 'Nokia' + model_replacement: '$1$2' + - regex: '(?:NOKIA|Nokia)(?:\-| *)(?:([A-Za-z0-9]+)\-[0-9a-f]{32}|([A-Za-z0-9\-]+)(?:UCBrowser)|([A-Za-z0-9\-]+))' + device_replacement: 'Nokia $1$2$3' + brand_replacement: 'Nokia' + model_replacement: '$1$2$3' + - regex: 'Lumia ([A-Za-z0-9\-]+)' + device_replacement: 'Lumia $1' + brand_replacement: 'Nokia' + model_replacement: 'Lumia $1' + # UCWEB Browser on Symbian + - regex: '\(Symbian; U; S60 V5; [A-z]{2}\-[A-z]{2}; (SonyEricsson|Samsung|Nokia|LG)([^;/]+)\)' + device_replacement: '$1 $2' + brand_replacement: '$1' + model_replacement: '$2' + # Nokia Symbian + - regex: '\(Symbian(?:/3)?; U; ([^;]+);' + device_replacement: 'Nokia $1' + brand_replacement: 'Nokia' + model_replacement: '$1' + + ########## + # BlackBerry + # @ref: http://www.useragentstring.com/pages/BlackBerry/ + ########## + - regex: 'BB10; ([A-Za-z0-9\- ]+)\)' + device_replacement: 'BlackBerry $1' + brand_replacement: 'BlackBerry' + model_replacement: '$1' + - regex: 'Play[Bb]ook.+RIM Tablet OS' + device_replacement: 'BlackBerry Playbook' + brand_replacement: 'BlackBerry' + model_replacement: 'Playbook' + - regex: 'Black[Bb]erry ([0-9]+);' + device_replacement: 'BlackBerry $1' + brand_replacement: 'BlackBerry' + model_replacement: '$1' + - regex: 'Black[Bb]erry([0-9]+)' + device_replacement: 'BlackBerry $1' + brand_replacement: 'BlackBerry' + model_replacement: '$1' + - regex: 'Black[Bb]erry;' + device_replacement: 'BlackBerry' + brand_replacement: 'BlackBerry' + + ########## + # PALM / HP + # @note: some palm devices must come before iphone. sometimes spoofs iphone in ua + ########## + - regex: '(Pre|Pixi)/\d+\.\d+' + device_replacement: 'Palm $1' + brand_replacement: 'Palm' + model_replacement: '$1' + - regex: 'Palm([0-9]+)' + device_replacement: 'Palm $1' + brand_replacement: 'Palm' + model_replacement: '$1' + - regex: 'Treo([A-Za-z0-9]+)' + device_replacement: 'Palm Treo $1' + brand_replacement: 'Palm' + model_replacement: 'Treo $1' + - regex: 'webOS.*(P160U(?:NA)?)/(\d+).(\d+)' + device_replacement: 'HP Veer' + brand_replacement: 'HP' + model_replacement: 'Veer' + - regex: '(Touch[Pp]ad)/\d+\.\d+' + device_replacement: 'HP TouchPad' + brand_replacement: 'HP' + model_replacement: 'TouchPad' + - regex: 'HPiPAQ([A-Za-z0-9]+)/\d+.\d+' + device_replacement: 'HP iPAQ $1' + brand_replacement: 'HP' + model_replacement: 'iPAQ $1' + - regex: 'PDA; (PalmOS)/sony/model ([a-z]+)/Revision' + device_replacement: '$1' + brand_replacement: 'Sony' + model_replacement: '$1 $2' + + ########## + # AppleTV + # No built in browser that I can tell + # Stack Overflow indicated iTunes-AppleTV/4.1 as a known UA for app available and I'm seeing it in live traffic + ########## + - regex: '(Apple\s?TV)' + device_replacement: 'AppleTV' + brand_replacement: 'Apple' + model_replacement: 'AppleTV' + + ######### + # Tesla Model S + ######### + - regex: '(QtCarBrowser)' + device_replacement: 'Tesla Model S' + brand_replacement: 'Tesla' + model_replacement: 'Model S' + + ########## + # iSTUFF + # @note: complete but probably catches spoofs + # ipad and ipod must be parsed before iphone + # cannot determine specific device type from ua string. (3g, 3gs, 4, etc) + ########## + # @note: on some ua the device can be identified e.g. iPhone5,1 + - regex: '((?:iPhone|iPad|iPod)\d+,\d+)' + device_replacement: '$1' + brand_replacement: 'Apple' + model_replacement: '$1' + # @note: iPad needs to be before iPhone + - regex: '(iPad)(?:;| Simulator;)' + device_replacement: '$1' + brand_replacement: 'Apple' + model_replacement: '$1' + - regex: '(iPod)(?:;| touch;| Simulator;)' + device_replacement: '$1' + brand_replacement: 'Apple' + model_replacement: '$1' + - regex: '(iPhone)(?:;| Simulator;)' + device_replacement: '$1' + brand_replacement: 'Apple' + model_replacement: '$1' + # @note: desktop applications show device info + - regex: 'CFNetwork/.* Darwin/\d.*\(((?:Mac|iMac|PowerMac|PowerBook)[^\d]*)(\d+)(?:,|%2C)(\d+)' + device_replacement: '$1$2,$3' + brand_replacement: 'Apple' + model_replacement: '$1$2,$3' + # @note: iOS applications do not show device info + - regex: 'CFNetwork/.* Darwin/\d' + device_replacement: 'iOS-Device' + brand_replacement: 'Apple' + model_replacement: 'iOS-Device' + + ########## + # Acer + ########## + - regex: 'acer_([A-Za-z0-9]+)_' + device_replacement: 'Acer $1' + brand_replacement: 'Acer' + model_replacement: '$1' + + ########## + # Alcatel + ########## + - regex: '(?:ALCATEL|Alcatel)-([A-Za-z0-9\-]+)' + device_replacement: 'Alcatel $1' + brand_replacement: 'Alcatel' + model_replacement: '$1' + + ########## + # Amoi + ########## + - regex: '(?:Amoi|AMOI)\-([A-Za-z0-9]+)' + device_replacement: 'Amoi $1' + brand_replacement: 'Amoi' + model_replacement: '$1' + + ########## + # Asus + ########## + - regex: '(?:; |\/|^)((?:Transformer (?:Pad|Prime) |Transformer |PadFone[ _]?)[A-Za-z0-9]*)' + device_replacement: 'Asus $1' + brand_replacement: 'Asus' + model_replacement: '$1' + - regex: '(?:asus.*?ASUS|Asus|ASUS|asus)[\- ;]*((?:Transformer (?:Pad|Prime) |Transformer |Padfone |Nexus[ _])?[A-Za-z0-9]+)' + device_replacement: 'Asus $1' + brand_replacement: 'Asus' + model_replacement: '$1' + + + ########## + # Bird + ########## + - regex: '\bBIRD[ \-\.]([A-Za-z0-9]+)' + device_replacement: 'Bird $1' + brand_replacement: 'Bird' + model_replacement: '$1' + + ########## + # Dell + ########## + - regex: '\bDell ([A-Za-z0-9]+)' + device_replacement: 'Dell $1' + brand_replacement: 'Dell' + model_replacement: '$1' + + ########## + # DoCoMo + ########## + - regex: 'DoCoMo/2\.0 ([A-Za-z0-9]+)' + device_replacement: 'DoCoMo $1' + brand_replacement: 'DoCoMo' + model_replacement: '$1' + - regex: '([A-Za-z0-9]+)_W;FOMA' + device_replacement: 'DoCoMo $1' + brand_replacement: 'DoCoMo' + model_replacement: '$1' + - regex: '([A-Za-z0-9]+);FOMA' + device_replacement: 'DoCoMo $1' + brand_replacement: 'DoCoMo' + model_replacement: '$1' + + ########## + # htc + ########## + - regex: '\b(?:HTC/|HTC/[a-z0-9]+/)?HTC[ _\-;]? *(.*?)(?:-?Mozilla|fingerPrint|[;/\(\)]|$)' + device_replacement: 'HTC $1' + brand_replacement: 'HTC' + model_replacement: '$1' + + ########## + # Huawei + ########## + - regex: 'Huawei([A-Za-z0-9]+)' + device_replacement: 'Huawei $1' + brand_replacement: 'Huawei' + model_replacement: '$1' + - regex: 'HUAWEI-([A-Za-z0-9]+)' + device_replacement: 'Huawei $1' + brand_replacement: 'Huawei' + model_replacement: '$1' + - regex: 'vodafone([A-Za-z0-9]+)' + device_replacement: 'Huawei Vodafone $1' + brand_replacement: 'Huawei' + model_replacement: 'Vodafone $1' + + ########## + # i-mate + ########## + - regex: 'i\-mate ([A-Za-z0-9]+)' + device_replacement: 'i-mate $1' + brand_replacement: 'i-mate' + model_replacement: '$1' + + ########## + # kyocera + ########## + - regex: 'Kyocera\-([A-Za-z0-9]+)' + device_replacement: 'Kyocera $1' + brand_replacement: 'Kyocera' + model_replacement: '$1' + - regex: 'KWC\-([A-Za-z0-9]+)' + device_replacement: 'Kyocera $1' + brand_replacement: 'Kyocera' + model_replacement: '$1' + + ########## + # lenovo + ########## + - regex: 'Lenovo[_\-]([A-Za-z0-9]+)' + device_replacement: 'Lenovo $1' + brand_replacement: 'Lenovo' + model_replacement: '$1' + + ########## + # HbbTV (European and Australian standard) + # written before the LG regexes, as LG is making HbbTV too + ########## + - regex: '(HbbTV)/[0-9]+\.[0-9]+\.[0-9]+ \([^;]*; *(LG)E *; *([^;]*) *;[^;]*;[^;]*;\)' + device_replacement: '$1' + brand_replacement: '$2' + model_replacement: '$3' + - regex: '(HbbTV)/1\.1\.1.*CE-HTML/1\.\d;(Vendor/)*(THOM[^;]*?)[;\s](?:.*SW-Version/.*)*(LF[^;]+);?' + device_replacement: '$1' + brand_replacement: 'Thomson' + model_replacement: '$4' + - regex: '(HbbTV)(?:/1\.1\.1)?(?: ?\(;;;;;\))?; *CE-HTML(?:/1\.\d)?; *([^ ]+) ([^;]+);' + device_replacement: '$1' + brand_replacement: '$2' + model_replacement: '$3' + - regex: '(HbbTV)/1\.1\.1 \(;;;;;\) Maple_2011' + device_replacement: '$1' + brand_replacement: 'Samsung' + - regex: '(HbbTV)/[0-9]+\.[0-9]+\.[0-9]+ \([^;]*; *(?:CUS:([^;]*)|([^;]+)) *; *([^;]*) *;.*;' + device_replacement: '$1' + brand_replacement: '$2$3' + model_replacement: '$4' + - regex: '(HbbTV)/[0-9]+\.[0-9]+\.[0-9]+' + device_replacement: '$1' + + ########## + # LGE NetCast TV + ########## + - regex: 'LGE; (?:Media\/)?([^;]*);[^;]*;[^;]*;?\); "?LG NetCast(\.TV|\.Media|)-\d+' + device_replacement: 'NetCast$2' + brand_replacement: 'LG' + model_replacement: '$1' + + ########## + # InettvBrowser + ########## + - regex: 'InettvBrowser/[0-9]+\.[0-9A-Z]+ \([^;]*;(Sony)([^;]*);[^;]*;[^\)]*\)' + device_replacement: 'Inettv' + brand_replacement: '$1' + model_replacement: '$2' + - regex: 'InettvBrowser/[0-9]+\.[0-9A-Z]+ \([^;]*;([^;]*);[^;]*;[^\)]*\)' + device_replacement: 'Inettv' + brand_replacement: 'Generic_Inettv' + model_replacement: '$1' + - regex: '(?:InettvBrowser|TSBNetTV|NETTV|HBBTV)' + device_replacement: 'Inettv' + brand_replacement: 'Generic_Inettv' + + ########## + # lg + ########## + # LG Symbian Phones + - regex: 'Series60/\d\.\d (LG)[\-]?([A-Za-z0-9 \-]+)' + device_replacement: '$1 $2' + brand_replacement: '$1' + model_replacement: '$2' + # other LG phones + - regex: '\b(?:LGE[ \-]LG\-(?:AX)?|LGE |LGE?-LG|LGE?[ \-]|LG[ /\-]|lg[\-])([A-Za-z0-9]+)\b' + device_replacement: 'LG $1' + brand_replacement: 'LG' + model_replacement: '$1' + - regex: '(?:^LG[\-]?|^LGE[\-/]?)([A-Za-z]+[0-9]+[A-Za-z]*)' + device_replacement: 'LG $1' + brand_replacement: 'LG' + model_replacement: '$1' + - regex: '^LG([0-9]+[A-Za-z]*)' + device_replacement: 'LG $1' + brand_replacement: 'LG' + model_replacement: '$1' + + ########## + # microsoft + ########## + - regex: '(KIN\.[^ ]+) (\d+)\.(\d+)' + device_replacement: 'Microsoft $1' + brand_replacement: 'Microsoft' + model_replacement: '$1' + - regex: '(?:MSIE|XBMC).*\b(Xbox)\b' + device_replacement: '$1' + brand_replacement: 'Microsoft' + model_replacement: '$1' + - regex: '; ARM; Trident/6\.0; Touch[\);]' + device_replacement: 'Microsoft Surface RT' + brand_replacement: 'Microsoft' + model_replacement: 'Surface RT' + + ########## + # motorola + ########## + - regex: 'Motorola\-([A-Za-z0-9]+)' + device_replacement: 'Motorola $1' + brand_replacement: 'Motorola' + model_replacement: '$1' + - regex: 'MOTO\-([A-Za-z0-9]+)' + device_replacement: 'Motorola $1' + brand_replacement: 'Motorola' + model_replacement: '$1' + - regex: 'MOT\-([A-z0-9][A-z0-9\-]*)' + device_replacement: 'Motorola $1' + brand_replacement: 'Motorola' + model_replacement: '$1' + + ########## + # nintendo + ########## + - regex: 'Nintendo WiiU' + device_replacement: 'Nintendo Wii U' + brand_replacement: 'Nintendo' + model_replacement: 'Wii U' + - regex: 'Nintendo (DS|3DS|DSi|Wii);' + device_replacement: 'Nintendo $1' + brand_replacement: 'Nintendo' + model_replacement: '$1' + + ########## + # pantech + ########## + - regex: '(?:Pantech|PANTECH)[ _-]?([A-Za-z0-9\-]+)' + device_replacement: 'Pantech $1' + brand_replacement: 'Pantech' + model_replacement: '$1' + + ########## + # philips + ########## + - regex: 'Philips([A-Za-z0-9]+)' + device_replacement: 'Philips $1' + brand_replacement: 'Philips' + model_replacement: '$1' + - regex: 'Philips ([A-Za-z0-9]+)' + device_replacement: 'Philips $1' + brand_replacement: 'Philips' + model_replacement: '$1' + + ########## + # Samsung + ########## + # Samsung Symbian Devices + - regex: 'SymbianOS/9\.\d.* Samsung[/\-]([A-Za-z0-9 \-]+)' + device_replacement: 'Samsung $1' + brand_replacement: 'Samsung' + model_replacement: '$1' + - regex: '(Samsung)(SGH)(i[0-9]+)' + device_replacement: '$1 $2$3' + brand_replacement: '$1' + model_replacement: '$2-$3' + - regex: 'SAMSUNG-ANDROID-MMS/([^;/]+)' + device_replacement: '$1' + brand_replacement: 'Samsung' + model_replacement: '$1' + # Other Samsung + #- regex: 'SAMSUNG(?:; |-)([A-Za-z0-9\-]+)' + - regex: 'SAMSUNG(?:; |[ -/])([A-Za-z0-9\-]+)' + regex_flag: 'i' + device_replacement: 'Samsung $1' + brand_replacement: 'Samsung' + model_replacement: '$1' + + ########## + # Sega + ########## + - regex: '(Dreamcast)' + device_replacement: 'Sega $1' + brand_replacement: 'Sega' + model_replacement: '$1' + + ########## + # Siemens mobile + ########## + - regex: '^SIE-([A-Za-z0-9]+)' + device_replacement: 'Siemens $1' + brand_replacement: 'Siemens' + model_replacement: '$1' + + ########## + # Softbank + ########## + - regex: 'Softbank/[12]\.0/([A-Za-z0-9]+)' + device_replacement: 'Softbank $1' + brand_replacement: 'Softbank' + model_replacement: '$1' + + ########## + # SonyEricsson + ########## + - regex: 'SonyEricsson ?([A-Za-z0-9\-]+)' + device_replacement: 'Ericsson $1' + brand_replacement: 'SonyEricsson' + model_replacement: '$1' + + ########## + # Sony + ########## + - regex: 'Android [^;]+; ([^ ]+) (Sony)/' + device_replacement: '$2 $1' + brand_replacement: '$2' + model_replacement: '$1' + - regex: '(Sony)(?:BDP\/|\/)?([^ /;\)]+)[ /;\)]' + device_replacement: '$1 $2' + brand_replacement: '$1' + model_replacement: '$2' + + ######### + # Puffin Browser Device detect + # A=Android, I=iOS, P=Phone, T=Tablet + # AT=Android+Tablet + ######### + - regex: 'Puffin/[\d\.]+IT' + device_replacement: 'iPad' + brand_replacement: 'Apple' + model_replacement: 'iPad' + - regex: 'Puffin/[\d\.]+IP' + device_replacement: 'iPhone' + brand_replacement: 'Apple' + model_replacement: 'iPhone' + - regex: 'Puffin/[\d\.]+AT' + device_replacement: 'Generic Tablet' + brand_replacement: 'Generic' + model_replacement: 'Tablet' + - regex: 'Puffin/[\d\.]+AP' + device_replacement: 'Generic Smartphone' + brand_replacement: 'Generic' + model_replacement: 'Smartphone' + + ######### + # Android General Device Matching (far from perfect) + ######### + - regex: 'Android[\- ][\d]+\.[\d]+; [A-Za-z]{2}\-[A-Za-z]{0,2}; WOWMobile (.+) Build' + brand_replacement: 'Generic_Android' + model_replacement: '$1' + - regex: 'Android[\- ][\d]+\.[\d]+\-update1; [A-Za-z]{2}\-[A-Za-z]{0,2} *; *(.+?) Build' + brand_replacement: 'Generic_Android' + model_replacement: '$1' + - regex: 'Android[\- ][\d]+(?:\.[\d]+){1,2}; *[A-Za-z]{2}[_\-][A-Za-z]{0,2}\-? *; *(.+?) Build' + brand_replacement: 'Generic_Android' + model_replacement: '$1' + - regex: 'Android[\- ][\d]+(?:\.[\d]+){1,2}; *[A-Za-z]{0,2}\- *; *(.+?) Build' + brand_replacement: 'Generic_Android' + model_replacement: '$1' + # No build info at all - "Build" follows locale immediately + - regex: 'Android[\- ][\d]+(?:\.[\d]+){1,2}; *[a-z]{0,2}[_\-]?[A-Za-z]{0,2};? Build' + device_replacement: 'Generic Smartphone' + brand_replacement: 'Generic' + model_replacement: 'Smartphone' + - regex: 'Android[\- ][\d]+(?:\.[\d]+){1,2}; *\-?[A-Za-z]{2}; *(.+?) Build' + brand_replacement: 'Generic_Android' + model_replacement: '$1' + - regex: 'Android[\- ][\d]+(?:\.[\d]+){1,2}(?:;.*)?; *(.+?) Build' + brand_replacement: 'Generic_Android' + model_replacement: '$1' + + ########## + # Google TV + ########## + - regex: '(GoogleTV)' + brand_replacement: 'Generic_Inettv' + model_replacement: '$1' + + ########## + # WebTV + ########## + - regex: '(WebTV)/\d+.\d+' + brand_replacement: 'Generic_Inettv' + model_replacement: '$1' + + ########## + # Generic Tablet + ########## + - regex: '(Android 3\.\d|Opera Tablet|Tablet; .+Firefox/|Android.*(?:Tab|Pad))' + regex_flag: 'i' + device_replacement: 'Generic Tablet' + brand_replacement: 'Generic' + model_replacement: 'Tablet' + + ########## + # Generic Smart Phone + ########## + - regex: '(Symbian|\bS60(Version|V\d)|\bS60\b|\((Series 60|Windows Mobile|Palm OS|Bada); Opera Mini|Windows CE|Opera Mobi|BREW|Brew|Mobile; .+Firefox/|iPhone OS|Android|MobileSafari|Windows *Phone|\(webOS/|PalmOS)' + device_replacement: 'Generic Smartphone' + brand_replacement: 'Generic' + model_replacement: 'Smartphone' + - regex: '(hiptop|avantgo|plucker|xiino|blazer|elaine)' + regex_flag: 'i' + device_replacement: 'Generic Smartphone' + brand_replacement: 'Generic' + model_replacement: 'Smartphone' + + ########## + # Spiders (this is hack...) + ########## + - regex: '(bot|zao|borg|DBot|oegp|silk|Xenu|zeal|^NING|CCBot|crawl|htdig|lycos|slurp|teoma|voila|yahoo|Sogou|CiBra|Nutch|^Java/|^JNLP/|Daumoa|Genieo|ichiro|larbin|pompos|Scrapy|snappy|speedy|spider|msnbot|msrbot|vortex|^vortex|crawler|favicon|indexer|Riddler|scooter|scraper|scrubby|WhatWeb|WinHTTP|bingbot|openbot|gigabot|furlbot|polybot|seekbot|^voyager|archiver|Icarus6j|mogimogi|Netvibes|blitzbot|altavista|charlotte|findlinks|Retreiver|TLSProber|WordPress|SeznamBot|ProoXiBot|wsr\-agent|Squrl Java|EtaoSpider|PaperLiBot|SputnikBot|A6\-Indexer|netresearch|searchsight|baiduspider|YisouSpider|ICC\-Crawler|http%20client|Python-urllib|dataparksearch|converacrawler|Screaming Frog|AppEngine-Google|YahooCacheSystem|fast\-webcrawler|Sogou Pic Spider|semanticdiscovery|Innovazion Crawler|facebookexternalhit|Google.*/\+/web/snippet|Google-HTTP-Java-Client|BlogBridge|IlTrovatore-Setaccio|InternetArchive|GomezAgent|WebThumbnail|heritrix|NewsGator|PagePeeker|Reaper|ZooShot|holmes)' + regex_flag: 'i' + device_replacement: 'Spider' + brand_replacement: 'Spider' + model_replacement: 'Desktop' + + ########## + # Generic Feature Phone + # take care to do case insensitive matching + ########## + - regex: '^(1207|3gso|4thp|501i|502i|503i|504i|505i|506i|6310|6590|770s|802s|a wa|acer|acs\-|airn|alav|asus|attw|au\-m|aur |aus |abac|acoo|aiko|alco|alca|amoi|anex|anny|anyw|aptu|arch|argo|bmobile|bell|bird|bw\-n|bw\-u|beck|benq|bilb|blac|c55/|cdm\-|chtm|capi|comp|cond|dall|dbte|dc\-s|dica|ds\-d|ds12|dait|devi|dmob|doco|dopo|dorado|el(?:38|39|48|49|50|55|58|68)|el[3456]\d{2}dual|erk0|esl8|ex300|ez40|ez60|ez70|ezos|ezze|elai|emul|eric|ezwa|fake|fly\-|fly_|g\-mo|g1 u|g560|gf\-5|grun|gene|go.w|good|grad|hcit|hd\-m|hd\-p|hd\-t|hei\-|hp i|hpip|hs\-c|htc |htc\-|htca|htcg)' + regex_flag: 'i' + device_replacement: 'Generic Feature Phone' + brand_replacement: 'Generic' + model_replacement: 'Feature Phone' + - regex: '^(htcp|htcs|htct|htc_|haie|hita|huaw|hutc|i\-20|i\-go|i\-ma|i\-mobile|i230|iac|iac\-|iac/|ig01|im1k|inno|iris|jata|kddi|kgt|kgt/|kpt |kwc\-|klon|lexi|lg g|lg\-a|lg\-b|lg\-c|lg\-d|lg\-f|lg\-g|lg\-k|lg\-l|lg\-m|lg\-o|lg\-p|lg\-s|lg\-t|lg\-u|lg\-w|lg/k|lg/l|lg/u|lg50|lg54|lge\-|lge/|leno|m1\-w|m3ga|m50/|maui|mc01|mc21|mcca|medi|meri|mio8|mioa|mo01|mo02|mode|modo|mot |mot\-|mt50|mtp1|mtv |mate|maxo|merc|mits|mobi|motv|mozz|n100|n101|n102|n202|n203|n300|n302|n500|n502|n505|n700|n701|n710|nec\-|nem\-|newg|neon)' + regex_flag: 'i' + device_replacement: 'Generic Feature Phone' + brand_replacement: 'Generic' + model_replacement: 'Feature Phone' + - regex: '^(netf|noki|nzph|o2 x|o2\-x|opwv|owg1|opti|oran|ot\-s|p800|pand|pg\-1|pg\-2|pg\-3|pg\-6|pg\-8|pg\-c|pg13|phil|pn\-2|pt\-g|palm|pana|pire|pock|pose|psio|qa\-a|qc\-2|qc\-3|qc\-5|qc\-7|qc07|qc12|qc21|qc32|qc60|qci\-|qwap|qtek|r380|r600|raks|rim9|rove|s55/|sage|sams|sc01|sch\-|scp\-|sdk/|se47|sec\-|sec0|sec1|semc|sgh\-|shar|sie\-|sk\-0|sl45|slid|smb3|smt5|sp01|sph\-|spv |spv\-|sy01|samm|sany|sava|scoo|send|siem|smar|smit|soft|sony|t\-mo|t218|t250|t600|t610|t618|tcl\-|tdg\-|telm|tim\-|ts70|tsm\-|tsm3|tsm5|tx\-9|tagt)' + regex_flag: 'i' + device_replacement: 'Generic Feature Phone' + brand_replacement: 'Generic' + model_replacement: 'Feature Phone' + - regex: '^(talk|teli|topl|tosh|up.b|upg1|utst|v400|v750|veri|vk\-v|vk40|vk50|vk52|vk53|vm40|vx98|virg|vertu|vite|voda|vulc|w3c |w3c\-|wapj|wapp|wapu|wapm|wig |wapi|wapr|wapv|wapy|wapa|waps|wapt|winc|winw|wonu|x700|xda2|xdag|yas\-|your|zte\-|zeto|aste|audi|avan|blaz|brew|brvw|bumb|ccwa|cell|cldc|cmd\-|dang|eml2|fetc|hipt|http|ibro|idea|ikom|ipaq|jbro|jemu|jigs|keji|kyoc|kyok|libw|m\-cr|midp|mmef|moto|mwbp|mywa|newt|nok6|o2im|pant|pdxg|play|pluc|port|prox|rozo|sama|seri|smal|symb|treo|upsi|vx52|vx53|vx60|vx61|vx70|vx80|vx81|vx83|vx85|wap\-|webc|whit|wmlb|xda\-|xda_)' + regex_flag: 'i' + device_replacement: 'Generic Feature Phone' + brand_replacement: 'Generic' + model_replacement: 'Feature Phone' + - regex: '^(Ice)$' + device_replacement: 'Generic Feature Phone' + brand_replacement: 'Generic' + model_replacement: 'Feature Phone' + - regex: '(wap[\-\ ]browser|maui|netfront|obigo|teleca|up\.browser|midp|Opera Mini)' + regex_flag: 'i' + device_replacement: 'Generic Feature Phone' + brand_replacement: 'Generic' + model_replacement: 'Feature Phone' From 892f29455d64fc3e0c9470e4f15101dac7b643fd Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Thu, 10 Dec 2015 14:56:34 +0100 Subject: [PATCH 073/626] Creating an import profile --- .../Domain/DataExchange/ImportEnums.cs | 12 + .../Domain/DataExchange/ImportProfile.cs | 22 +- .../SmartStore.Core/SmartStore.Core.csproj | 1 + .../Mapping/DataExchange/ImportProfileMap.cs | 3 +- .../201512091408315_ImportFramework.resx | 126 ---------- ...1512101150534_ImportFramework.Designer.cs} | 2 +- ....cs => 201512101150534_ImportFramework.cs} | 24 +- .../201512101150534_ImportFramework.resx | 126 ++++++++++ .../SmartStore.Data/SmartStore.Data.csproj | 10 +- .../Import/IImportProfileService.cs | 3 +- .../Import/ImportProfileService.cs | 3 +- .../Controllers/ImportController.cs | 122 ++++++++-- .../Models/DataExchange/ImportProfileModel.cs | 13 +- .../Administration/SmartStore.Admin.csproj | 2 + .../DataExchange/ImportProfileValidator.cs | 8 +- .../Administration/Views/Import/Create.cshtml | 24 ++ .../Administration/Views/Import/List.cshtml | 8 +- .../Views/Import/_CreateOrUpdate.cshtml | 124 ++++++++++ .../Content/1-165-0001-produktcsvexport.csv | 219 ++++++++++++++++++ 19 files changed, 677 insertions(+), 175 deletions(-) create mode 100644 src/Libraries/SmartStore.Core/Domain/DataExchange/ImportEnums.cs delete mode 100644 src/Libraries/SmartStore.Data/Migrations/201512091408315_ImportFramework.resx rename src/Libraries/SmartStore.Data/Migrations/{201512091408315_ImportFramework.Designer.cs => 201512101150534_ImportFramework.Designer.cs} (92%) rename src/Libraries/SmartStore.Data/Migrations/{201512091408315_ImportFramework.cs => 201512101150534_ImportFramework.cs} (79%) create mode 100644 src/Libraries/SmartStore.Data/Migrations/201512101150534_ImportFramework.resx create mode 100644 src/Presentation/SmartStore.Web/Administration/Views/Import/Create.cshtml create mode 100644 src/Presentation/SmartStore.Web/Administration/Views/Import/_CreateOrUpdate.cshtml create mode 100644 src/Presentation/SmartStore.Web/App_Data/ImportProfiles/produkte-importieren/Content/1-165-0001-produktcsvexport.csv diff --git a/src/Libraries/SmartStore.Core/Domain/DataExchange/ImportEnums.cs b/src/Libraries/SmartStore.Core/Domain/DataExchange/ImportEnums.cs new file mode 100644 index 0000000000..498c39b3d2 --- /dev/null +++ b/src/Libraries/SmartStore.Core/Domain/DataExchange/ImportEnums.cs @@ -0,0 +1,12 @@ +namespace SmartStore.Core.Domain.DataExchange +{ + /// + /// Supported entity types + /// + public enum ImportEntityType + { + Product = 0, + Customer, + NewsLetterSubscription + } +} diff --git a/src/Libraries/SmartStore.Core/Domain/DataExchange/ImportProfile.cs b/src/Libraries/SmartStore.Core/Domain/DataExchange/ImportProfile.cs index 38633e4fed..ccff94629c 100644 --- a/src/Libraries/SmartStore.Core/Domain/DataExchange/ImportProfile.cs +++ b/src/Libraries/SmartStore.Core/Domain/DataExchange/ImportProfile.cs @@ -1,4 +1,5 @@ -using SmartStore.Core.Domain.Tasks; +using SmartStore.Core.Domain.DataExchange; +using SmartStore.Core.Domain.Tasks; namespace SmartStore.Core.Domain { @@ -15,9 +16,24 @@ public class ImportProfile : BaseEntity public string FolderName { get; set; } /// - /// The type of the entity + /// The identifier of the entity type /// - public string EntityType { get; set; } + public int EntityTypeId { get; set; } + + /// + /// The entity type + /// + public ImportEntityType EntityType + { + get + { + return (ImportEntityType)EntityTypeId; + } + set + { + EntityTypeId = (int)value; + } + } /// /// Whether the profile is enabled diff --git a/src/Libraries/SmartStore.Core/SmartStore.Core.csproj b/src/Libraries/SmartStore.Core/SmartStore.Core.csproj index e876d7b408..6ca1700faa 100644 --- a/src/Libraries/SmartStore.Core/SmartStore.Core.csproj +++ b/src/Libraries/SmartStore.Core/SmartStore.Core.csproj @@ -168,6 +168,7 @@ + diff --git a/src/Libraries/SmartStore.Data/Mapping/DataExchange/ImportProfileMap.cs b/src/Libraries/SmartStore.Data/Mapping/DataExchange/ImportProfileMap.cs index 94b9d9a46a..c390eff79d 100644 --- a/src/Libraries/SmartStore.Data/Mapping/DataExchange/ImportProfileMap.cs +++ b/src/Libraries/SmartStore.Data/Mapping/DataExchange/ImportProfileMap.cs @@ -12,10 +12,11 @@ public ImportProfileMap() this.Property(x => x.Name).IsRequired().HasMaxLength(100); this.Property(x => x.FolderName).IsRequired().HasMaxLength(100); - this.Property(x => x.EntityType).IsRequired().HasMaxLength(100); this.Property(x => x.FileTypeConfiguration).IsMaxLength(); this.Property(x => x.ColumnMapping).IsMaxLength(); + this.Ignore(x => x.EntityType); + this.HasRequired(x => x.ScheduleTask) .WithMany() .HasForeignKey(x => x.SchedulingTaskId) diff --git a/src/Libraries/SmartStore.Data/Migrations/201512091408315_ImportFramework.resx b/src/Libraries/SmartStore.Data/Migrations/201512091408315_ImportFramework.resx deleted file mode 100644 index bf924882bc..0000000000 --- a/src/Libraries/SmartStore.Data/Migrations/201512091408315_ImportFramework.resx +++ /dev/null @@ -1,126 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 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 - - - dbo - - \ No newline at end of file diff --git a/src/Libraries/SmartStore.Data/Migrations/201512091408315_ImportFramework.Designer.cs b/src/Libraries/SmartStore.Data/Migrations/201512101150534_ImportFramework.Designer.cs similarity index 92% rename from src/Libraries/SmartStore.Data/Migrations/201512091408315_ImportFramework.Designer.cs rename to src/Libraries/SmartStore.Data/Migrations/201512101150534_ImportFramework.Designer.cs index 2d56b77d1e..8f8b2e1554 100644 --- a/src/Libraries/SmartStore.Data/Migrations/201512091408315_ImportFramework.Designer.cs +++ b/src/Libraries/SmartStore.Data/Migrations/201512101150534_ImportFramework.Designer.cs @@ -13,7 +13,7 @@ public sealed partial class ImportFramework : IMigrationMetadata string IMigrationMetadata.Id { - get { return "201512091408315_ImportFramework"; } + get { return "201512101150534_ImportFramework"; } } string IMigrationMetadata.Source diff --git a/src/Libraries/SmartStore.Data/Migrations/201512091408315_ImportFramework.cs b/src/Libraries/SmartStore.Data/Migrations/201512101150534_ImportFramework.cs similarity index 79% rename from src/Libraries/SmartStore.Data/Migrations/201512091408315_ImportFramework.cs rename to src/Libraries/SmartStore.Data/Migrations/201512101150534_ImportFramework.cs index 06901ed24c..dda44fb555 100644 --- a/src/Libraries/SmartStore.Data/Migrations/201512091408315_ImportFramework.cs +++ b/src/Libraries/SmartStore.Data/Migrations/201512101150534_ImportFramework.cs @@ -16,7 +16,7 @@ public override void Up() Id = c.Int(nullable: false, identity: true), Name = c.String(nullable: false, maxLength: 100), FolderName = c.String(nullable: false, maxLength: 100), - EntityType = c.String(nullable: false, maxLength: 100), + EntityTypeId = c.Int(nullable: false), Enabled = c.Boolean(nullable: false), Skip = c.Int(nullable: false), Take = c.Int(nullable: false), @@ -59,14 +59,15 @@ public void Seed(SmartObjectContext context) public void MigrateLocaleResources(LocaleResourcesBuilder builder) { - builder.AddOrUpdate("Common.Files", "Files", "Dateien"); - builder.AddOrUpdate("Admin.Common.RecordsSkip", "Skip", "berspringen", "Specifies the number of records to be skipped.", "Legt die Anzahl der zu berspringenden Datenstze fest."); + builder.AddOrUpdate("Admin.Common.ImportFile", "Import file", "Importdatei"); + builder.AddOrUpdate("Admin.Common.ImportFiles", "Import files", "Importdateien"); + builder.AddOrUpdate("Admin.Common.RecordsTake", "Limit", "Begrenzen", @@ -77,10 +78,6 @@ public void MigrateLocaleResources(LocaleResourcesBuilder builder) "There were no import profiles found.", "Es wurden keine Importprofile gefunden."); - builder.AddOrUpdate("Admin.DataExchange.Import.FolderName.Validate", - "Please enter a valid folder name.", - "Bitte einen gltigen Ordnernamen eingeben."); - builder.AddOrUpdate("Admin.DataExchange.Import.Name", "Name of profile", "Name des Profils", @@ -99,6 +96,19 @@ public void MigrateLocaleResources(LocaleResourcesBuilder builder) "Specifies whether to delete import files after an import.", "Legt fest, ob die Importdateien nach einem Import gelscht werden sollen."); + builder.AddOrUpdate("Enums.SmartStore.Core.Domain.DataExchange.ImportEntityType.Product", "Product", "Produkt"); + builder.AddOrUpdate("Enums.SmartStore.Core.Domain.DataExchange.ImportEntityType.Customer", "Customer", "Kunde"); + builder.AddOrUpdate("Enums.SmartStore.Core.Domain.DataExchange.ImportEntityType.NewsLetterSubscription", "Newsletter Subscribers", "Newsletter Abonnenten"); + + builder.AddOrUpdate("Admin.DataExchange.Import.FileUpload", + "Upload import file...", + "Importdatei hochladen..."); + + builder.AddOrUpdate("Admin.DataExchange.Import.MissingImportFile", + "Please upload an import file.", + "Bitte laden Sie eine Importdatei hoch."); + + builder.Delete( "Admin.DataExchange.Export.LastExecution", "Admin.DataExchange.Export.Offset", diff --git a/src/Libraries/SmartStore.Data/Migrations/201512101150534_ImportFramework.resx b/src/Libraries/SmartStore.Data/Migrations/201512101150534_ImportFramework.resx new file mode 100644 index 0000000000..641f298bd8 --- /dev/null +++ b/src/Libraries/SmartStore.Data/Migrations/201512101150534_ImportFramework.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + H4sIAAAAAAAEAOy923LcuLIo+D4R8w8OP50zsY/ddq+OWLuje05IsmQrti9akmzvvV4UFAuSuMwiq3nRpSfmy+ZhPun8wgHAGwgk7iBZpa4Xu0QkEkAiM5FIJBL/6//7/3/7n4/r9MU9Ksokz35/+ebVTy9foCzOV0l2+/vLurr5H39/+T//7//z//jteLV+fPGtg/uZwOGaWfn7y7uq2vz6+nUZ36F1VL5aJ3GRl/lN9SrO16+jVf767U8//fvrN29eI4ziJcb14sVv53VWJWtE/8B/HuVZjDZVHaWf8hVKy/Y7LrmgWF98jtao3EQx+v3lxToqqosqL9Crd1EVvXxxkCYR7sYFSm9evoiyLK+iCnfy168luqiKPLu92OAPUXr5tEEY7iZKS9R2/tcB3HQcP70l43g9VOxQxXVZ5WtLhG9+bgnzmq/uRN6XPeEw6Y4xiasnMmpKvt9fXuabJH75gm/p16O0IFAj0h5R+mKwJHtF65XNf//2ggP6t54p3r56++qnVz/924ujOq3qAv2eoboqovTfXpzV12kS/wd6usx/oOz3rE5Ttqe4r7hs9AF/OivyDSqqp3N00/b/dPXyxetxvdd8xb4aU6cZ3GlW/fz25YvPuPHoOkU9IzCEoKN6jzJURBVanUVVhYqM4ECUlELrXFsXT2WF1uR31ybmPyxHL198ih4/ouy2uvv9Jf758sVJ8ohW3Ze2H1+zBIsdrlQVNdI1dZrFab1Cp9lFgpuMNl2Dh3meoigDhqnBV55FZfmQFytcUKEYD98XZYdwclpcJlU6PcUP89XT5I18QlWEOZqQrZylsXeojItk0yicGdqbZ64+JmssFqvLnAp06cvJ5yhboeKg/J6sblHli63B8s88m54OTVPfi2iDF9gKKzGh7yb1L+7yh9G8+Y38EDM3KgLolyLJC6qV1frdQHlcRreB5+K318Pqq16To8cjvNjc5sWTy8ocPb5iMOwXZ3lbmmX5bz/9ZDTJluz1Lik3afT0hbC8DaMa888Fqio6FmvewSrhJrmtCwr9qsWz5yBnDno7DQd9i9I6xEph2SyllZ66Tjz7MY+jNPkTrbo2Hbi3xdEwr4Bwz8bytprpsJtawMSKsts6urVkEQAPmTqE6fO+yOvN/Aq6b3+ppueS78/RfXJLGUgyky9fnKOUApR3yabxp4iSdTWAnxT5+jxPIYHuoa4u8rqIyfhyLehlVFDz2k2n9N3yVCUtnr0GkbelWQjfTCQu7cy0VFeuxFO0j2v/UaMLlB9hHKrWA2zcTtLo9nSNB3uSpEhD7l/MRqvZ4lap734s8KabylJ5579PdDXBlTqTqu5mMs5RSXVcKVegHKRch8oAe904UqNS6E7pultnHOogBhqHc69h9brO17rqaL3M1qVrfaEtzGlJpOssrW+TTFAiuqqXeR1DyiecVeWvFEDbSqtCnJTCGSrWSUmE8xzF1KlvrRAuUFwTf90rHtdeEcjbCnSYZLv5NznIevvLL1O0PXhDJ29ZKrxHlLdRQcQKXtZ5Hr7iqgwirIYUZFgD7iXELCoXh2FbvXzFItpLr7P0TiRBJwVCF5hVN7Q9P+P5Mno8fkTrjfepF0bUGuIEDzcF6qoHcZXcex8+nZaNVmuY3w9XUP1oqpR4zTCxYuJ3HIZ6zM26yLH82yskUq2k/+6VkLytUHuJJU2RNiZi8gPzYE4Hcmb+JfuA5eOMmvR+2A7SNH94X6OywvuSb3nljdDDJyKcE2G5e4cZ82sVd5jIn5fJWlv3OFs51vT1Nblt24imAbdpowLRpBuVQhacUu3j2gdZ+YDVmbRTTflVo0bH3WKKRJXOlXvr8AaZlyZvUOz1uUJHYSrtpi7/XK+vUfHlhmiw0m8AUzh1G/HxEzFI9iERtOkTJhd16CiMPg7qihXGcWclYKBukMF66wkWsZe2YBEF0xkvDqMStR0g1O0M3S6GTiudDZmsZdRgCZhq9iG21XGKlwsiiPthv0rI2+po9L5O+lab37bHniVuV3cCGeII8hjPcjp5KwZR6WEbOsmLdVT5LtgdtosorSbv+sFqnWRH+XrNRAxPd5OhDOZjOri5SdIEi4svtcN4nN6hFAW4R9E5rg7iOK+BEO4pfFdh+OhjVFanm4PVCm/RVNcZTANGNBqvQERTfsnA/aR1sElZfcxvk8x1g4rrUy7CqlqKwtkgaEkqOZvoVP8VAzaYAWKpsPoDILZ262GSpnia+7lXdZOHBfo6BpF3mIOz7TVv6am63cJcDRaN2G8eRrCypYCQie13YtWjljqEYQg5sfUnU6oeHz8SgyZKD+rqjpg0MQVS7XJUNcBpMKogzIlZLdsJwmZAvT7LywoeW18MDkQsFXoNgDh1sbnrKe8jLZd3clwM95KDse0m3fPDPaRFYOfGJUK/uGLbLp0jvMfALPIHddGCXRuBgF2EIYSuSsDsu/wQFauzPMmq8kOCkZATd7DfApyk93I4YAwKYNuRdEedRmuNAAyoPw5GrgB5QFsVeHGX0/pHeBN7io0yuO88FEh+KZBAezmkl1unJ6jDPaT1Os9etQj2e3p5WydJUVaBXLd683WWhnSb/jCtYBbbRNn017ePyAatEO/WaI/QKoS/3SdZLG5dNS0yF2AnG1Yrmm/maujt5A39M9kQWylKNbH8gU6V7/IMNYcfk7d1Ej3O1JLfflu+k2lkCFwKu4W2hxkWQK5IWLT5cuu1mhVSZec4SLGLIwBpR8dQfk73jlzWa/O7pEAxMc9etTj2y7O8Lc2COdG1KBobUraOjyCBJmWw4MGH/CMiRDwt57g0dXlXIGTa4M8BGsSKFhVJzDXmGEdTX/8Li9pl/i3ydvFuw9WpuQJ2zvEuGM8Bxt1x7SdU3eUSF9IY5mqo3Ki3ZOwQ00MDuyttFev9LbsQSIY1WiuA1REEEDsPQnltC8f0cLk10iLgpm6/DinUknodmirTyYyZpMLppdPbDNP66I5IwiRaiVEsc+gj3pq0UGFu8j02dj0MzBGmvXjL25I5GcKGAE5lrV5fF+g+iTRqIsyJ8DbYQU77XMf1XBB+5arvFb/Vn5AGCONqce1lXiHzLal8hd4kGsP0MrguauVgs8Gs5y98QeM6vm5Wkzit+iOZ0BEDssMnaWiBk1gfpvltH/BlLdKkdvmKwbEdobhtZy7R4/RRbGTwxKMcLui3wwiyFEPrqwFwYCeoXGAlEMibjZquePAQQbBfC+RthbrPFyoVr2WzgfIouzg2W2b3Tk3UrWwtviM2LNPRGM+r8Egvo9vpk0gvc//PME+2qatD39i25ckOM7LAKbsmOhFk1inYi+K0GvLOT+WSGeT6aI8VukIqFILL9RjCL6NPka/quDrHu3H04LKPi6oI9+jVCM92GH5tl7ZlgVS30hBuFiP1PKqYUz03onxA6eamTv8LlZeYU9IgyD7nLrjk1+Wa6YfvyrHcetVDMrfkIADxfhwIZX25k8XS0iLDm/NjhcdYVueKk2fJiKQ1xAugZtX87oJ29PfVPvv9glYbkub8b6EVuE2aqZkm8A2hZb8lZYKhT7NVcp+s6ihNn3ztkGUOwC7ucmwJz2gnnuD+zdnerNcCO65F600a4EZf2HwsHZ5w55D7DU2Ym6t0m9/dS6IrVLDdfmM9XdTrYFv9QBg7dNSI4gbt3cdwSPsIp4N423JNX/yopxe6KKtvopiYIAVeRyttlG6YZt9XiUrAwzRyWr5PbqqjqPA+7OnwhLBWyB2ppEBfqjtM8WY5CfAUGMU5GD+ae81BlFpNbGNyERHbRgerFdcH7zGdlu/yhyzNI/9z8haP78x9zdJGwDuE3mP81IXFf7kRcDpmIGrRHD9ukuYNpXfRE4/TDAW9KE5RhGD7D1F5EWGrCYWa1TE2ywsquDckg8jBbYEQazi6dmaEbBavyWl5TjJXFwEContER09xippO+eo4FuMZKpLcW/p6nHTtp4g9ZeWUhpQfZ6RKgHwYIRPcYn2aEMmL0g5jEwzY+69RnKyJb+qswL/aR5L//vLFBUm1jtdPh+4Hy3dyWh6X3uRkng/0ZRxs4pBzyeweiyZG18Qceu/cqjz+8Y86an0dXiq72a5RjAf3UYLrJimD1TM8DOyp84KVZAFH/jF/aEbdpiTxDh7Mq+TmiToETvKi6+MhwrsvP8SHUfyDvg9K3gH3TuNDdoME42lDS7wD6Te93hYF3fTjWUrW9TrMJDUYo8dwGCkB0KpFlqAZjFUsC6SDh/XTYV1Vg3PBQ7YI9PekvEuTsgqDtBX+FGHmxXp95L9xPvzE1jlFl8Te/qURkuAr0Jd0NW0D7cbkiB7DTtTGxQbjiVLLgZjj7OMayOG1Q4QCi6uNc3DE1LmzjrMKFWUQ/mrV1ggzmpgpWsU2a5t483GZoEYmvRU+XkNRWR1UWHVe1xU6ytfXSdYe6wVkQtxnrPNoqjcSQpsm/hbzd5Tc3k0niuN9THD035PVhNg/TEubfqXx1Sc9Ij9lEu7EItzlijBpErcoTFwcYHKPiidS2dJ70pmB2AQTD1p1lnSJ2tUnyLa7x/cJRWVdINIlhTkZ5FXKvs2DNRsO6atie7Tkxxi1GWnrbJUieqKl8UCFca837Z2hguRrCuX4GCEl1AiNk000ZY1YnvqyWRL7JRIMkulKr1roy3zwlQ+BMXIoIRhGAWobIshqA1WEz9UYUIjnGZXLApTGQI7xSc2syhOUCWBXLR9Io6tkoLIgJCm8LfG7nUnj8NLEWHVuMUWYGA8iG4AA59hx9hBR2XcWUNF/CEw2BhDWcRxnCcWjHEILo+g9ByHrOA/m2Of+EDxcWKEy5s63v3QHetOmL+23Lcr+w1UU41FXkI1PU8txvM11B4VCHcGJ+pQplqpTFsZRm36LigQbddA+Utl9RT3FBBnUks2SSVXHqeJRWw3cYrS2Q3QeF2unK3lwDCgyIVsu5cIRkHUiM+5sWNFZHlTs7hhC2mEOzLbLrA8H6G5fDHGGUCjwggjhFdPcmYpOyTBao7b/tY9rlrelifKd6E3zbmZCRGp8LcleKcbDDRCT2nVMxBjcqdU1Zbsrtz75XeJqYRtdVR7l9SbP2MRuzp4pAdNkGU+6maHxkVTKfHl0wESIZxsHotvGX+aarZi48WYrqPbyA5ywLCmBbRcnwMUwhUdCPwbBeWHskWhRtZwvv2fZtwnXAMYBAcqHAkL7pavpH5N3vmHUodgvxfK2NEvxRBduyP2XQC3rHPjz3ZU4zCvMp7Ne60mTaIbXmVoxCnWhZ39hJtArdeRGX6gAwNbTZnlSRW5SXSR/Ir+2R1d/ysscr1gornjczhE5LZ4v4+CxydJn0Q3peZTdKmO2wvBA4Ltx4eMXtvjm0Ladgoc739/m8/SbCBta3xL08GmS5xtCHz46bFn0B5DA/sbYC9uoaThZXX9S1QExSeq4MjE5HQ/gl6Gk64G17f4JrZLoVVt/b7gr1FdDosMki4ohZL39y0SQdHGGa5rERbmETXIXH+UnSYoy9e7g50CXHz+jB1+9fVpeFlFWJiFuSE2T4tLl5FZUITCE9uSW0zdu6mSE0z/nyF69mKYemWpbMZ9t5LSUOkuD5BhNJjSWEhw25kLXV0VqJOsjNcYvGOR0jcG3l2Kl3FByBZA/nuzndYqMHiQPlKxygyY/tWpfYgqUpb+/lBoG3fD+A95AMM83W3psBjS9hp8+0yjTaPREmKd/6Ge2hrvZ0HuBQrfc+iss5+n4ESsqbPtFM+6Rh/iH6U6QpLtj5XmT29ozisL1eN+ERbRfbeRtaRYCw3sF1kf0aV58QI/forSev/XWMP2YkzVn6jsVrlaw7T5riNn232oNuPaSI28r0G5rFGHviyxY4oY45AUgeazUwikntQc1M2eYTFLMgmyYrufZULJCl3f1+jpjXv12RdYmDt2eE5znePQiPwrpmKLhEcObQVytK3aRUNwSklfT3xhS1LU9N+GuNU17FUriWNFenQroDWLaMhqAedeDuIV0Ux3S7uBQ780QeVsD0bzz93RED4aI2vfej6iV2OxowkscVg2Ndml04TK6VCu3BnrYR5IDRGtymPZyKm8rkIUfKnbstDzBVk895DVd0B6Tv/PXc6jBteEBWH5vuP8hkT0RcIJ13uWis66/IVd49uaxv25gse31w+T6gSX3X0JHjLnV8Ir+uJL6nv7oD4kcyitMoD98kg2Y9D+ILgmkRPbaY5uvhMwapM9wwv5Ww3bdatjfQ9jBewj70Pxn5B9WBcaNF3cxLA4qFwwFECjEbgPOTuO/74Dx7m0IlfIJsgOBCd9o0CApxhtvWID8ec1NrHbYIS5jTRLyqt8QhM4jJdkkGGafMh2Yik8cRqtGZ0oCFRZLuihReWlO9VCdFacK7V5v2io87zcfwkTobo8GC5cgbwZRt0ulZ6Q1/PQiSCZ1uxI8A30cqgs60AXHBMovuNrbK7y/gmpScS+smRYQOV4X+Yitz07tMrr135ZhJHvRchatUH5c3VodLLOrZB0Fs7/68KYie6o/zyqQ73lZ3tYcz/zO8t7uQm8JB33nxvbVGDU2y0diNGHKlm/CaOLhtvMRi4OyTG4zLEXdWckcj8Mt8hLKaUmfPfQ/ewnjjhx2mv+5TgNYrRqdF+4RSerr/FJXX24oUmr32p/SeD+MocpLrnkzw7SqzLFmXH+CIIvp8r87DNbVxWqaJ13VtiaFumlVl2FrE68bW4njQXhcK2UR7W0/eVuafcxEFzuNoitCXuvc7juk0NrcZnOzW0d8d2Pht2B72ZO3FchwatEEO9Agb7fhT8xD7JNZYadlm5HAO4qEWZeyqshTgm0rEyPZWzQuD7sYLuLOBgvPcy7jAf2upnVsR6g+1DAYKo+YXpmyeqCH1riSal4tDZT1TZ/yUSMJ4eELuJjsVxGDVWSePOULHSVNFobraym1GVFCm0sU7Z7b5W1J6OYfr7ZDQqSJgiU5ey7+qKMClee315MPqvHhrv6FJWGNJkwg17zWPkNDfveYJ9sSUtUQwqz9mGQ/mAx1iySysbW2tsfOMrQ7zYw1pxVpeHjQMQF4h2C/zijktqXR+zrpW21+294jKPsHHr8W3sl9AFSTLSRdW1NlQSc7ddS8GDj5WAyynodp6PgRj6kMb69Cy9Szya9urPr6N0k9LO8ex179ydsKZB3AyVltr3W5J+QNc8BrGd/hnkWDGajmRd8xKPSsLwshGC0SsJDHs5avD8t7qHJR2u7imxfkP6B0c1OnGSpL/x28gDKYWnlBIljartAnaNqpatfNlyYC3PTOVwK/R2U7wHBhDaMOqsx7gcBXXFXBoNfUkJnwumpeDIjX6vIoXzvm6Ce1XzEotoPH2s7o7q6Hcms0jaHH6Y+lCKWdErVJub3DCDI6M7FXA+DA1lC5wMQgkDfLOuYp7vl1n5tY44uJsts6uvU/sw0kg/YXc4sQ4mjZ7AlVXXO3GixxwjIPuDcJOBoN4Z1E4mCzKfJ7tGrxHQFhtrbXKPMqPNLAqTOCJpjY57RxG5l0je10qXSNpUviADVeYEeF4Oo6hrDdKzHrMxw14GQF8Kf+SlPByQogDq0ii9KDuroja1pzYe0cxZhvXXZPXQagVyrEe5NBoYRaCvqaDMdrJtn8pP5QMsvN6G4S5XWcsE22R28ztvyF8DLlvnmaOohjvE2dp0H8532yQsWUz5JpPWOg4lQpkquh5qBJjSoIS4BZLa8d10le1OuzvHRxEdC65asexV6Fytu6zDdJHMotHSLcdv7NzOnZwWpVUA/oxPEhu5CVTalfepEClYlYKmgOAMTWeqQoKNtqusgCQp0cyhXdZID89VnbGS+FRnHsNZq8LUqlrdFoZLZCRCpd1Nf/QrFKO/5tmgtKnxtBKP26/y3BOzBPB0ZUVqQn3jFfLZ5QU9zha/SunSPqeSwIjXqUrgjjYljXcjBOa4Kugy0Q2Dv6U9W1BsB/CfDU/nvFL2+LEuh9kdebifPYmeZN3poIf1CrU7721MlhFgeiQYPsQ57jEvHXygk9yLBcm1+xQJw2Z8pgbc4C+GvzthNeKp3i2Ot1hZJ59tr4Wcp44PNHtcqAz5Gs1AV/fiTVJ07qop1ba03RpNBp/tsrCXlblEDaJGeBDhxIW963IYIGBHu/6J2kKSZW6wj1dlZgEdwo0BmQ9wKzRR2sI2GwnUVP5DQ5KLJPqLrLV1OeJEk45qguCpTFT0e45gyNNo2dR9VgAKujx//uLAuX0WO7oIZwvH2L9LkTA6qVi/q6wioxPc3i9JKgDRVqr2rs+HGexi5JY3huYhLONNcIR43OM9JW68wzwraxWUeGG7IQZfvGRsoRryIJMRGi9AShqWkqb3lqAstbnpraLX7V+WdADTc5k3ayPm0rVK1M1gQ2vOtshVa2CWGtm3mIitVZnmRV+R0VCLOdf0zv0R2Kf+T1cMd7zq200PgsKVQ70yNUDPvBzU2SJgFei+z3B5vJaUCDqsmmBqM/KhDWX0eYt8a2kzNLYUwEw/QTSbo8ixku0GbCV0jLH2glm5JJR3h0f/92loaOHzdJQR0Jn/JsSPM9U5v/haLp6cnKV5Pc9R26TgK8b92jOojpuvkhT1cz8IfY8EyMyTR8GGU/ZtkAc23OomLYNk+P5myOXlcZ8mTM0eTpdTSDcdGuptQA7K+wTi33Nd4QFMmfVNPQFBVRTH4OpsHsTc8iMrLGz1HJJAOeUMNviCN9XoKLjc402ov6urfR5x3yWV3Ed1GJ5nTgn0WJ69XBzgPSbNOnn5e2ObI/xwpnUzenJbN7jQM9cL29x5PsTvgckaM35rFeo2OLDxHJQtR6cT7nVf+iWbijzvEpDXjkScXoigccjj2hciFSAgSyjclTxg02LUAhg+MSSdecAwU739DXEu/SPyQleSAB7CAEeNUe4g6dlUMJx8kKUNvXNt8nN3Qjpx0EBHj1tUSr70l1JwxGDy0MyqCK7eBoLXJXU8Hf9Cqn0H+uSOgsX+7UMyzYklTXfbGkZ0MR3DOm3LZn52iF0BqtWCV23FjgQEdZKC1TaIGFwehrWL8ui/suvyzclYpkH5eIb1KOi116tTHSxgIkr+04AInS46H8MmeCitDhlZkGTQkqzH3Airyt/hjU08PbaDVfN7GXXaZdbc1X2KGGZpHtPgqyooa2tRdanTKFgWDU8bHmcpJ02FpwDUSDsO3FXN5WRy9fCR2toCGQtVn7JzpYnEihdNQ0t3aHGhpDt/soyKUa2lahcIbWHEa70YBgm85L4fgrmb1ikbfV+c0YrQCl6TPTTiEC5SYOVTgtu87Sp1qjAN6oDuFRXm9mcmqfY2JsSIrpWbx2fWvzJLi5QBnZx84xsqapeYb1CW+2aJasidshL8B13EHdh0v7WydyQNkvyUZuJ2EBNx0NrEmV47mS1RFHJAGVrsoyeK8lmemh1w2UfQ5Tk804JpL37ZAgdv7Zog/b8JZvllQ0jfnUIbx9Q5NH7M4xmllGMnWEcefbaGzEqUk2bm1q2i0S5jpveGv3/E2ANLSnZYcsmBn/EQtINjwtZLkFItq6eU/NnEM0d+nqbJUibGZF0wcyNAr+iObJC8XfUkPpoCzzmEQlrzpjBT71CGglySw/nVXl79+1OGgEj2uAg0hjg1TxlsiA+0x8S0QoVHTtLMRbIv3BpaddSVDs7Up5W0GswWaevDWS/WJMr2LmQ7DHVu5pNZrA7GAfFDfg4N9J2ICDda+s0wC+vQwq+C7QVfuG4CFwHEZplA3PcbmfBU3sup3LgTaRZlAGskHRLlBYmwpOUBtK4PAnToEDgkxGE/C4qQvjcdCFXURNH0O013/ytoLYIJdFFP/AFJ8p0Jte0g27u6M8g1zDx9+hNLlHxZNj9dltH+PgOl7oJbF3tiF/8kBQFuJq0AFiB0cA0iDAMZRXqicWZQiltHe66yWS0ilIJJ3LW3dh/OVaYQgpBzJ5haXFcb+C2TE7R3/UyOkZh9ZBMEKzlwOFHIRIKBZMCEJtl8IcPp2jqMyzk7xouGl+N0jLv4i6vYMcEPh1QH15ymxq+Rf0pov2qKKbm/bmxdQHK6t1kumv9v7tpyAPgox0W5i8clt0xc51R83QRLKXhiCAfScI5rnZzKlxdoQXIb94Ch7TfmVTyX+Ale0sKlr7xvKEsDnPc6jITnGICMtgHsgwYSHLpFjCIokKzEMkLGIyj2UYo2MXVPHA3JLdxVhLXbHw7B5DCgbsNOSwQe8YCw1Ba4kUSN9vZ4+s6nxXaAU45pXB6Lsc5NBXSLHmvggKqParoLwtTWC16RvCth5b9FjhT+vN9ElISAD0H3VSBHhWnPjQCHzL8KHwnpaX0ePxI2Ko4YoKIzrCbHCbF0/BFuKjPKuKPA1ha4R7kuC0pJFeyJpgcq3Paw16lw12E8OwV4AOG/SraR3BmWxc0cu/DLcSUAlTfHtNLG9LoNjED05NpNqpDX2w+hfmG9bdEdyabg7gZmjotMSYsNijOEBYqYcGNNdc8+ss3ka0VnaOZwFxXRC+bvMjed9DlyDcay15WzzJnnPmCX6sEk8jyENXYmXW92hWB/BGGlYMKmfhBGwvWQomfopT1CzNntJAEJ2hIsm9E0bQ0BeKzzPW8KLC0y6NV5lrMyDG0YTIR3iaJVUSpdusydguGmmxq3ENueoaAWr11Rja1uUlXf/nVstitjJLfe6klinT408f81sHjYxr3ZKAIAbLXhvL22LItE2nLuHyRW+HYuLIDIoyA3MlwA/SqwAT9JIKNujxAdsQdHIAlSt7G+YEWiBjCHVC4PcqRd5Wk2kZ9+ghL1RJn99M46jRuIcmegH3OCPAljaWMR/7LYX7JVDZFibPR3SPUv/3M/OiCnd9x7L1Eww+W/KdTZ+d1VvOHO0JXfjKLfpaTB9ngZkcFQUq5mhrxgAJDacVJEosi30DPvKsInuIqFS9QPQ3Jy5yM2JkxovSaAlnrNDXs9m3JRxUfvO+9ysB1V7/y9ti6eSdiijUBojOoL9ba5PEW+qqUUqiwL+gXMqhBClVgHrJ7FlB07L0C6+rwI7x7KVVIa0hwlsJD4WS1CFZg7cBWV//C8XKSPpfJgtbmt9iJRFMUYAoo9a9ffjUPIIVEGGfYtIX50Q6lGVjUI+O1crVGH5QpAowQZOqYG1dSmyeE33vWWhp3wcgXc8ZSD8fU/f8rIP27+uWw8+98pe31W47veP1whyIhQ7VUz2O0rPHFfAwilAoulYFCL+bPfEdWtUpuozKHw5sT6qVr1gke6aXt6VxaP4yjUPzALOLyr9j2qxuYcyz48cN4Uj1Rc83Ye4QNqcA0lb+vkXOYdD03XzJjovC38j5jC2+89rF+/Mxopcvi8qx7nG2cm21jmPMJ67tsmSbjsFOyw/JCgu27wThP2+JVJwhrMeFPKJmdfXu4ECDPs8fWm3dDzvJIhKxcJRnJDSAeAs/UXS0rbHMwR1wUKjNm59o5WrIxSk2+HOntzguSAQERveqR7Jf0eRtNaT3teIaLMtEg3dbB2Jd+Y7jFNuzaUAzku2b5LC+5dGrMSh7XA9BAAf2IJiXafm18JHC/FVffy+Az1kAL9L6dv5WQ0Vkfoyy2xovzXYzYP6oFGGMJPa5c0oCsPLsFY9pL1RTCxUe0fsirzfzMzduef5GRy/rzed7djhFMJa+yzu0Rt+iIiGoXLwjpH75aoRmL3fytiihAnDuLLcO/aThbZj92pTcT3G72G7kS9n8t+f2yfnQNl5IGeA0lY1XpqE8Z2R7rokICyPBH/JSmeMtkMflY36bnyUxkYDtSV7woVqnh/mKMYGmC4Zrgse6DMGfUfWQFz8mn92zIsGK6YmK8FHr1/JPMEVxHj/Gd3hXgMjTUs6oFVl0pI3AmXXICK+UtZgUOzpgMdeOtoZ9miBxZvQj48AlQxpBqccyBvXLHNR3y3otfZcUKCY3s151SPYrqrwt7fnaNA7EZmI0D+n+Mkl2U/PX6/7uupx8zAkCf7KauGFP8mKNJ522MG17H5N1glnsMm+sVe9DHiJg5d2i6TeWizK3HSPVbcfZCs9scAvLbnvzKaKZ4jx3OS2WvWqWt/UM/NQTbrUPo/jHaYZbiH94Xhs4iqoozW9fSTDuWTToBIMn9iGSzAa7fb1AyL+E9cDAfx2sYKNrK4TMSipr7ExMTqoBNR7HWYhUpZ+irL6JqE+huERrbFC4nRy1ugRCt1ck8raWWZ++JegBd1V9BW+Sll1tVvMNdJsxNAAv86j2fLzn49n4uFXuAdiYw7Tn4j0Xz8bF1FAiTxG0RpAzE48R7XlY3la/q3gTaHfydpmTJvMVv8jLEtvgqT+X8aj2fLatfGa+jjbJ6T6h6i53iS5t65evRoj2jKGYUJZQTVoo/bo6yfJGsuO8Q4yLzL8HTjz4jxrVaHWM+Sk9qKoovnPMO9te7ShfgQj3PClviyGY93193BM8CeSoa8RUxAnEzYgAaqsa1UZhoKiSkwS4zaBZ0/F6yV/6MYn28LK+J8rh9ilZI9LmDC3Lr/QnkksboKBfNeCDQ1EOJfgSFaC23lAGlUXfR7V0Q2C+Go6EreHlFx31M4im3utnhaYrkrzwfk2OsNP8d6ZJq9pokiDXmPP5B3eZzzK0c7RJn4KMz6idWcZ0dDR5E4dxPHkb+vxEgewQEkQ6fQhpyEiXC6zcLovE+/kAjMYpJ2Oz+MVxXvs/VYI7sSKHd1Ga9rMQILlJvzLDCU4C2wh86npzq8J0QCzJdSO6GgODAxnBqGycMaCXaTPulrttw+LZGzcaMVVtL36ZJOCzdbzqdlWGjesvQMw/wrO84HNk2MYqlngmwxDIem9flppU6RO13NyuuShTazUvEu8duomwVONVlcoCrmWH1OJYf72JkluXMLdeX3U49rpK3pZGW0x1MVdrY07UcCCbc8lwa6/odPMwsUaIPMIRejHkUO2l0VkaJ/KI4l1lY9o1SQPR9An/n9ceM1S+kJDbu8B3WLx2i9I94huHo4ih9luv2j9raxvrys/oofyIiKh7Buj3KhPGuNec8rZginkn+l9oKxdGn4T1fU14xeUTikrMtM2j2F43YUeY9vKikBe1pTHRq10LPxp2Tkg39Z3Y6QLfWuZ+h8U3K91WGEFSemR7YdkLy3MSltP1Ji8q3OpN4pSfa1R/LxzbJhwneYo5Z5m2B17zv7McJvHRj2Tj15HL6Afyw0C2U6T+UZ7dJLd1MQ6Wmy5DUFqvs/6m/tStkdkZkjY6T1fzJALuI3kUIVz6n/F7DcBZ5UinXY3Bh9NKOZRwXqkA9Xt54imL3dMvkGjFLt3QKwbVXovrdJp3UAHlD3WK0TfTpNoxSv8w0YJA85Q9VguZiZTmkzywyQ+TCuKp5TsFTa2uT1NraNoYUcyCktYZ21ns5ioxD8N4JMryHdqk+ZPjhQAexV6jydtqVyVflbaUiRnEMDwtm8kO40n8Z+Jt+gysG8J8NojmCJQRUh+8EaYhbfLSINlLq2pzWURZuU7og0whpgLCOb4qQ1UXDOaw1WicI4FuUZscyxmcjQaaHtqewSuhAQcX5syRSElyjz4xyQ49Qo1cApZUmXxuZHdu+EX1qgce9kQyGGFHJAX0i+B89HNmjervjQZ5W389ZxZRpuRXS6rJFY7pBeEgeZzz+wQTdtE7yadlu1R1wusZIxLIY+jnghJ5CPPOHPs7/CdZFudwLXbc0zg02RuwkzV5jkqsd0+zG9XFqDBNfbm5KZFnMDWNMfJDcRhV8d1F8qen8/kMC3nzIsX2RGCRdwrpA8Q29mOwG094r3ZQxHchokgcnd5SW2wwjuA7Ql72GH8jSGu4BXOuj2wsqXNdDiUxJQM41+s1a0pqUhaclidpdFv2s+p7XUjWUjArFEsH1tLpE1nLGHEdT+sntL5GRad00vz65Qv6Cs/vL38SWGAES8wjbL4iksYd9ZXeqCs129IWFogqbCZENUmKzbL3BI2OR+QtLThBFwlRnWf0jpHZNH3CHUk2uLskSzwZ4KjyG5MpOCjLPE4oCbv1jWa3bxQ1XpqpeF51j/px/T/OVi8asVXWGoR88IxAFfC6QEeEiYlF+veX/5cwfNMGe4XINNgNgWvkzXhMuJEv2TtE1rAXB9TmItdyyjhaiWoTU3Q1/tIKDbkjhC2oErNHklXiBjHJYjxvqc1QOCSG+0zSyb45vgSvDygjW0SbOTTpB/sEpNifvlmOmDra/faaYVYDHsb21arrmyEDg1Wk3MtCW7Mu3NTu8a1yHHMxrXLedoJjsS3frkLAq8OllGvV1SDO5WvYMK6mNYB5x48wK1uyIVaepnqJHkGBpMjJOm0x/BHCnRJVsOszSCc4B7shkLjnB1n5gIoryicqpmDgZHzWgNhyG4sY4DeIgbeD14COz8RtwFyYtEzgF+O1C7yfJqFaTTLJK2x7YRssrtDqiLhkaOoVGZfoq0IcOa5lw5UG7UHLAC3UGUk2FMO7PkR9lXiDetWhl3YaggbpwgJakQVswZwSy0utcgQzyK5yjkzab6ssJsStr1PLjBwcxIYtiA0D8ljNWe+nV69Ex44TC0n6MAPzSGi6S2wzVj26aR5LS1gWGuMGGEmpJcOzE9ifGZkKpLVJ+6OKizFY/w7UcBgj4wARFGKt4dUqc94CMAOMZca0LmM/TFJy7Ns1oO3mGD44FTj05qQQpcuBGu0D08PzY7r+8hVU9GhhXcgiNKNwKGyfAaUbxQwaSzdfRush887eIvrqMM1vyTmG3sEjQEJ82QHZMKSIeKecPdLuz8CC0jnZCacP6f1RvqZH5j3jqLiEB5ZxYAtny4QCeoAPZQy+HXwoG8FMrCibH5PmuzrLuSCbN2POEvrQ5FX7v9wTCYKDDskRpJVTEm4D8k3CyJfnSvUQ5vBSKufJyFnZVNkaxmxfpDJlGv4B2CkYk3s0Vmxj+xlzPIQFGHM8T0aMObz1vMxet33LVKsreUBwR9PCWG1leLzmmjGc40TWiTl2IBK67oJWe5eUTdrxgw2eFJJFsB2N6vxFVQliqg7ehqmUbUB7ZDPG9SJNK+k2hOmqTEeWvgVztR+AJt2Pc/RHnRSoCfHVdhqqZUOZoOuVaf8AugJw+kl0UmtGpJtBxxmRyKQfXf2l7bgrzDfJPSqe6L1/jYU1AlbYcA7G2xg1xGtsPydbPlW9mc8KA+lsxFVMvaU567DOVik6rdD6oKqK5LquUHNr6moo0TGcCQ4FH0qrOzCoUVfkaw8z5m3dfNiMcD5ZsGEBI89OX2t7BKQdiuFeWlbPSBC8OJ9rbwc32LqxLMHX8Cya8/LSG29xQPaMPB8LuzBvSNNC3pVFeG8HHT1t+727od/yaphAqKDgNhf/j7QZi2361ihK6Sjm41LpfJl0oauzNVxqqBN5+Il5dIeXctkYFmDQHVSi5GmTm4g6XQutxxwChhiThbPhShD/Et5zVUdm4CsVnXfBi94y9WgYI57QqCVpRYUWdOU5bZMA/6na2hq9qB3RfApSO58mXWHrbRVnG67oUJ2Z+HmHV3fVOBZi4B1c5dv2LzYoTm6SJg1J70YzZWB1bQUrwxUdmFrTgx1kb7MRzcfoZnO8CywPj+QLfRztSsKRMvZzwAXeLFSgsbpo6NAd6AqPkVguLyoew51BcDx4w6R3MIYtXUiUDO6m29XkXWzJUXbLWNZg0V9e4vzHvviKZcI37vLX4FlaCrtl+TK6VWSHEWEDR2ywmOUmGC4OmPylwfktKpIoq/ppOcrX10lGAa3iWUzxKAinQOFAU+MOLR0gY9vR+fSC7Zya9GybwmpU4zPc0Bmg2AqO3+H9ncWwtkM0dnCnZzCqf9QRzRD7NUu8pILFsxWiMeoQIB+jgS+5GEAd3Q6Oh+bUpGdsvW3jfdcVwEHtB2Do56Tgt0erPyNV3g1F76kzRbAMgyvdccIYd43ll/C+2c63hRBsjbONHxxN7X0l41ZL1lQis5ASiieAqKj7IxcbndRurfQYDXg5STLiDwup4lEsLVxWWwNT+9/Fi7ZVlvzC5vqzsMmvLiLylsO7/CFL82il5a0xeGDu4pBDbsOun5PzFtyXGbkLprTRacCo5mIcdpmgAo+a5Ehlc6vLmAAGhzish7ThMQl6y0zwlM+WXqPVQ5mBRdVTZdIBtt4WMKjOESFATsCWu+hekPZ+VibcXRfCObpP0IOpH2wMrVh7G0CHFZhrYZdYUTmC+ZZteI52jiU/oHRzU6cZyfk6ZiojDpJW1zItU9OZf+WtyxkaFpktY2vtwObmc+08WzB+U3Ex9v+MHkp6x1SbzFWAhJi6A7JhYhHxTiVzlXZ/Bq6UzolJ24sncyW97/J/9oyj4hIeWMaBDslcQfQAH8oYfDv4UDaCmVhRNj8mzXd1lk/Db/awGwwePBH9Qg+4HT9WqMii9KCu7gh5mxBL7lE5KW2MakOkUlW0IZ9ZB3Yqe73VkGaQd6s5tvGNLKYATvKiXtMc1FoGF0Ehbu6hbFgXQG3Fp0G8wfJOzMBZcuLuDhtd5pskNuSjMayUkSiYNSdxyBdiJbgXc/ESTODdYaYr+u/7Iq83ak5iAKVsZM1BLFKAfZi+bd2aKev/XIwHzIdJ00OtbVBiDdcYKJlmyFOorwazjPm2lO+Ars+r8EbzYcx3W2B+Mfyit5KYAYc3wRjkMu4D+XpLWFAyhlltOHF+TJqnFRZjxS/FyvxJOggYYkUKZ8OGIGLzl+gC2W+qXszASCrqmjQ/rrkwR2n3A2OwgFy0mz4PuO+zcd1O7hi6nPVfy+gWfUhwb4qnPhG+lPGUtVSvHrAVXN6GgBtUPGOwfVxqNJQZmNZoDk36sfizB+BIGs1nxU+NGM/FvU1rAOuCOntL+XY0iKWYdjRvJp2gFZZd3Ol5l5pHOTjp8m57gM7j3R0WlPR8rhVenItdYjZd+JwAOQHD7WLInLT3s7LdDobKvU9uqqOoWF2d4S7fRSVafU+qu4GDZOyiqQexZVfFhit1zcjUIsT94S5WGPZqBt4znAYjTgQxLM6YIyOiZyEdv4C1VEzpajWqGwTYUyYFy+tQo6HMyNPKOTTpR1dnu3j4Kytidow8qjobN49b3R1D1HwwSzE1OJ8mnRlVXNZs/ZxXyGSPNMBJTVYCYm2yMnh3hzUlPZ/LWBXnYvv3SOfoAYvPWY4RlJ38aH3vqkoQGwLwNgypbG6nvPQmI5mBW03mbyc8+NBAzAwBbU1jtQfuf2wachMYsVmbpOJ3yYaGn6uJNAYDU4G3EFZpv8dYd2d5gTs+g7zC87D9i0vX72bP3LGKji9G0Cqms/XFwQ1AWa4lXL09LAgOYUZOBOfIpP0ewbLhBaQbG+OIFQ46YLABj9k8ZiWc203Zk7lsZxmNTXlqswWRK+eoqovsHP1RI5ObETA4bA4wkHaWM9jEjtnMqjHMYi2r5mkn7OSh04Z6T1Yh+KW9kArQyjLJabNHUVExb1Yrz2YUdWArZQxuZ6nIm5KfH8qflA63WBj0bBYzRDsVJr0Yai1oInMj0S4b0hqTM+Furh/aYSzBrzu5igij0IVVyCpMzqm7GGuhG8QSbLqDkRdneZp+yys8ivaCNflwkJUPqud65XXAdEQcuFUaIkVTELcOnd86hjUYygw8azB3Rmzb11rOSL9D8Y+85nMWC5/lRrshAtCIB+tamfSmrUPWgzDGreN22+HNwPq2821kZPCVF/SmxHWBSXF7Fj1RL+NplhC8unMdRS3YtzKuYOdeUTVmfrARZGdm1JlZ3CUGM2DUD6be1nBhd4QnsI0pj8gQmPCm09m5YfMAt+pEY3mlbDu6BdhfN98mXeLrLiYNZFrv8dx/zG+vmN+EZ6QCoKgD8TwDYsPnqlYgnyLX+a3jbIPxzMDMBnNn0guu6lawr9bPBgFPxLC76VhTjWBm3txJd5oRF+q4z5LrXLltK141WIjRdpbBaD6Ri/q6jIukeTDcLMsaWEWaMoaFtk4dAze1UOo1ZWdmYDQ98XeC7fB476MKfUIlCcq/OinytZbvFHXghPAsuF0aeHlD87OdQW/mcKHqiW/SC7betjDfZW7LekONSRmPaWZxthP7Mj/TiWQ36cNQa7k9xc1NkuIv6EoXUyNAgruJDshqLyFgnj33lbQLc+wEZIQ12psuHDR4EKdcJmgyKMWuFAKH96Wp/fGkBL1lMvXltwrqccyyO1XNk40dR+otF/JR5QV5PitZR8XT8WN8F2W36ByL2lFd4CbiJ3nsh64mGARCKllFfmhbAVm37fs0qtC4TzOwofEsmPRFgWY7GJT+YceZoyrhWXKMfmFeBDszNxOCBLfgvlH9xdjuMIp/nGa4L/EPOweLriLEgpI6NkypbXanPM+mo5mBt03ncyc8N7LB6OI8NfVm5uldDP40HMuCDL2DoaD/qFGNVsfrKEkPqiqK7+i5+0mi2F7Jq0BMDELbsLCiOdunzZfmYP1QZmBe/fQZOTKTBXdczBCumoHE6nzEsgoahnVk03ETAJOO+rx1elY3knl5FJwvky6w9baBUxlhY1nMTu2xhJlP2bKtAuyskJit4mb1iBZTvcCcmvSFqbYYe5+uN3lR4b7d0OUjvkOrOkWXUflDytfyKhBDj6BtGFnRDJTMgu35NF4GfYdmYEA98U060dZLsltSczHmO360Zj55Ffj5UEfmUzSzDPPpOzQD8+mJv3PMhxtK8yZUuWMTNU+IFeSMN8Da8x7QDmSHqhh8+aVbN5TZeFY+a4Zb/Jv5dkvHuE71hOtUuAYqOqlZR0X15fpfKK5IEXrEjBBTV1qUZXlFsfz6tURHaUH4o/z9ZVXUIjMT1BeoYl/VKl++aL4zfNU+YibwKFc9ejyKKnSbFwkCsfTlT1pc+Be53gihaYu0KD7mcZQmf6JVO4Nwp3gofdc+RtltHd3C2Noys86hi6qgdzhLynzS7nFwWuRnqFgnZZl07y1DiHkYLdLxs+ciwvHZuK6HeZqCvcLfjSo311ZlKLrbw4ZDUg1Hi6SNpQBp0oef6DpC9rQSqWnKDCSmTSrzCVV3OTjlYwg9QqxFEJaKe6xawZ6NAIyJTdVVVqlo3oJoUR6m+S15RBDC1ZXpualx2IKs1HnONSi6R2ogHMO7VDr6qFSnsd48S+KqLkAcbZEpQVSYRhDG5CHZpJICrSWzD4DpUaM0uUfF02WyBnvKlpsOfEiQoxg7m3bIFm1/zfgkSSuJEtPUMW1UyVRjGAPeauA/RVl9E9GpV/WdBdOi1uG0QtZ24GKD4uQmiakt1NNP0WO4gl5PgtW+0BMkUG0q4B0bM2/GlHiXEWh7DaWmiL5FRRJlw9X6o3x9nWSRjDj6WtqG/1FH9MvXLAH1DFvuOgqLrps2YYLbGinfGZoswaLzbUIMnRZuz+hADdyf3+l2Dwkq8DYONjX6Qi2az+ihlOnurkyL5PgR69gsSg/q6o7s2RohkhvTKnhtY/1byBBm5oFqEzTSHRz7FrUeUSTDYNYL+ja9tBe0VIuIZkCAcLTpJAxtDuaNDHgRhJ961GAHXuCAscOPqBhiVyE0o59MEJh3rUzQkDcepGialzY0aMTc7jC9wBzwBhsfmU05JLU2RCKj2Dj9tna0TPJUeJij3Lbavo0zlMH94zPJ6bYbfM4bcNshpiiyRStdcWTJl7S0hVJNyLhJkkrEsg0T3Ho/wXB1G3QVsDfqzVFR554aXZPrQeuPAntl0hvhBqdU84+D3rQWDHtXCrZZxvfSdFTrbsyA9BquIOmkkTnnACVxdPqjnclUblUwl1k0aL4WCjR9oX7hQRnCRpZSJfAwervuDm/lqV15DTsORwAGXqkcdkq0MetaLxQNopZ4Wfq4dJNOfIqoxpX2pS3Xe7Hg4EPQqSULILXYXl+i9SaVSAEEZ+q4elIh5mGMt6EKnByIgVYnYCuFv28MoR94kZclrpgqUPIw+oE3y4ncizsCMNgMAxEq8K4YjDQyR69Bqt9zMeFd4B5rFGOn5cn1JkpuQSHqyvRS0ywsSoEZgxjtTj+iCu8WdaIOQxr0OSqx9H5Hye0dSMYRgCm6dwnmhlLSUx5Gi3QUtAJh5IKEdMr4KYtVungoNtj3j0+H4b0+f5ZvhFQxXO7UnkPHHAurjw+vhsNHpo7iHHGowJ9is7lzFPX6UId+yNKDTeGg3LSJLsqBbWI4gOXjFMbEMiUke/yrpyIMrRkfWElKP/7UWkc9GPvEpONPkK+4E2KRfJoa8kGqK0JkBI7AFUTU4AcIyY3Vn5h5mipZbwygGAoLB1KmOXpXUWOEYmouGjJXN4f/8NBZEHXPGUjZ8PvgAQ0RWFQAGUBKOpBgfC5/hXUg1oUxNkSZsACRKga15KPTV4ZoJ4QYKOhn0AIkVsOI/cnKhidc9WEUACVBQMXQIHiQXlwEhYpcIM6JKdRlDlHQhgeRj4CDhOjBhMooSMEjmokIXDSLnBRjQP04xlPrTZYxOoA4aq5zoFB/rZfpqEgeAEo+GBEYIgwTn6UgDIALoIqUyD4EOUzSlHlYTEUVDtRgOOMaAejDIZyJSG0w15AlQEElAVY/Kr6Kik5D6JkBuQTECiswBL26gDWlFSgCyQciwEKkYULoFDQRUU1sFZIGj/I1jdAeIvlgeghw6nHw4N4MAyIF6CMltYvVPIrAu+oj8QDjGYZUGL5gBdCU5gMFVeY0jBWyqiXoAlCpc8HqqQTlflCOh0v6EIhKXFIHEWsQRd365lVcJMAo9CcHCsoXE5aoUsU8qmnZpQsFuTrYbNIErS5ztp8iUZTw8lGpqkHEYqKLFbRSYoWWLukUBKHcwJ8mdOuhbcbXVQpJsx7ntCLXNwyHRitIBlYwGCFULwDhQLQA7eBxhlLwV+Mwb6l6H8Np1fAIXKHajXT6GBlEonEoeyjaSEPI2dd/5SQzqq4dvAkWBYFVofN6yhs1Lpf30XWA8LPSdkJvm0irWBBgXNOI4pYk5lqYVo2KrVuR0YWAU5JuVqL1ttVw/UNKMxFWOyyhioJihtagFPPU1g3fsJ7JBFDzUekZzJFc83AXG0Gk2lCAcPLBQOAQibh7RArygBhn2Y6OWh5fbJIylLyOlgGkVRUsZk5GbSMASZXYA9FVL6MguN1A9bLqR8hZFwT4vpgBITUVtUNW11cQV3oXTk9mTZvTElx1AfBKdm0POLZ0QKM4gLTHBh55qi9Dqk5AHToAnX6ZMUVwOVHf6rQVHiU2V+5WU3hGMVN2xHhOJUzl4UboIorp3Ve5F4EF0+/7GWhvHwKLS66jmv6HooriKq6p38UYhZYCppgUlFZfSNZPgnEX5vPxqLqkX79NantRRb+STzknsxpRqo6M7507TccIhRdVWEwLTcyoC8DscPf4p5oiBwlxFwsHWXCi87Jc37WuNF+N6zoPXmmoTkFtpWHKw0xIf3qT9kpSaDEXajzWZFKis5ij7kqx/USpeyCfNC2XeBidhsuCpe43VfBmdudCqvrqIlpvUjSkEJFTh4PUD2lcwZtCHDrI9huSpHjTp0+HMn4/D6CPBFI+ILgCRB82YYuCQhKEM9ypGFpWLPEikMlQFMu4NVlmXarP0X2CHgxsHg5QKwFjeO+gOhjrjCT6gNLNTZ1mJFJ2VKClmbym4XClCMJSVd6MQjZlzTiQu8vGpAx4FYHkoxNgIXox+aEUhBJRTRzwShrsgkiHNFUwPQQ49Th4cG8uApEC9JGS2ifkXnvJUAKpiDIEKwSIt5/9EqEqDZky/t6sonzIRvUhimoSrSmobNbkxDH7fXY2JXUBKPm4RGCIbmzOOAWRAGRzUITmmdOThAPTDGMMLSVKlwFPRxUO3RxkuWLT30lowsJoRsCASqgR6cnAIgFoMErnF5I52myCSs5oYIzmsRlLGJ5ocMHEECjqpTTYpIwqtcHAmcg6M5YQqoNBJ+MQmMAOtKEZBQ2u1YFw8sFA4BBtuqSTCrqAqCa+Ste0qdKnHISu+yotakyDuXQnlKHzakirLg+WhyvIh6WspwqW59OAGkTOw20oIucno2SbT9WQjA205fgafpmQgE0DAPVgZnYVQbrRkdKLB9HIzwAplUL9PpXHNA8JFN4jEcik8wqvkTUh5vEVdXl4r85wj++iEq2+J9Udk1dXJI2uinxwmpoQ2Zgcwgqq6RDL2CnUrh5Kj3w1pDiW0xCuoB8oWE9FPwvNpG4DIKV0jkJR8is7ocbkHNeyHO+o8pSEHTc0ud4jWa41qp8B0eipAVKq8dqU2zqNx2CakgRAWm6lOaqElw9JVQ2ilCSruIJoyhYmtmOhtrUSqq9kN1hHsbHE6zpXjsmzqCdaSkIOQj6uMaAsARZ4d1WFZ0rBZNPSXw3J7uVEGAPqxzCCV5FEb6LBKKFwXxmVnbfOXTIyrUeBB9TtgTl4r/00j2tip8LoDQKNNgchVQoCqgBrhfFLCUqtAyKdWGkPndezkBTW4KzIgJEsT59mZif+AQrN9XIVuEqFSGvBukl4OEOpn+TI57oeLvRBJZdyYItBqqTTk35zyajQsMI/IYW1GJfCW+FJsZniXPI0/ZZXNN0yPS5ln0wFglsU4IpQE3kt/zAWBW5JnlZJyleXFQF8t+YKeCoHWCFM6yr0uyEKkMiyx3lU64lpe5CQA28MBbBbxg/vXJ1mCXlVW7GFUlVQGRyKerAxIzwbpLRnVOin3c2DzyJdiU8a6YkprWs+cBkKExKb7voNWwSorp1Ul5Szw+NMV8JDTSLNVeDyQStqgUloR89TKYipwgvZmMJbVUHJp7KPQDizgamsIidKzWUL6WhiSAsdDbRjn3PMwtti+tAjGFoTDQFWkoZYcA+86EItYOQTU278gtrVSZGvVaRTgSusNXkt+NoF9+6bMp5Zjnpe0l3mFoRjgI3HNtQJTDQG8cQk69/Yu1I4UUQghYLlYUF1zTz7p1LWAq6JHSb9637aOzwSSNXCA1WA17LUJNhWgnCGkOYL8pIe3hcn66h4On6M76LsFp3jaRre6gM2+dpKij25ri780EOuS+2rxwtSc3itMCwp6R/GNBxDGw5yVCkE1cYIpyaX5K1FpW2hrSMfqa4qmLxd+nKkgqTahqbOcy9pX+G001WxH6zChReUqPM49MC3G69OEng5UUDLByivBNFQ9uqkgoKKBia+TMu0fDV+ZFJJuzGs0cBGVTR0M6bWGClAK+5hzYm4bfTUpynTsZVsWYMlwZQsyLYDXn2XT5kDcUdPX16N35IWqaqAlg9TXgmiI/9Yp4J+CsTQKf/4He0Al99sKKeAlg9QXgm+22ZMOQXi2Sg3vGh6ddY9RSqjGwCrG5xYRU6z0QOsWrIBmCEtqJwNBdV+e91gISdTUZKhoi/77TWZiXXUfvjtNQaJ0aaqo/RTvkJp2RV0r9MONdsvLy42UUwOWf7HxcsXj+s0K39/eVdVm19fvy4p6vLVOomLvMxvqldxvn4drfLXb3/66d9fv3nzet3geB2Ptsi/cb3tW8LGM97uc6XkKbUVOkmKsnoXVdF1VOL5OFqtBbALbIBXX67/heKKHtE9ckvebz2puwbbHAzNzSBxDgk0cQh34OR3u08hTVFb/xXp0yvw4tNAwxM8LDL5dISImXFJPVzzIo7SqDhrH0ztNO8KjzxP63U2/M3znrz2xVNZoTX5PcbCfjfHdprFab1C2KJMcO1ow/VMKLXAXJ5FZfmAt/K4oELkQUYOOQRgjr+rPEY6fDXHdJlUKUfM9pM5jsN89TRG0Xwxx/AJVdF/oKeHxkXCYhqX2GF8h5gXvXmko0I7vADNmM/muD4ma8xaq8u826KzGIVCc7znKFuh4qD8nqyofmbR8mXmWJsa/8wzbujsd1ts34to08YiQEhHxba4L+7yB2CmhEJbvIc5OSHmBZovs5DlIskLrE05We6/WsryZXQLiDP9KmL67TWn3vkV5LWwhHALOr8gmS1X0aPyDSeLVavHJDjMTNYuVe1pVjBx7bJdtd4l5SaNntpADBbTuGRrZht/IEFEfhPdInGYZGnNbZ1gGvozRtF+sjCUCBH4gfQft4Y1Pua488mfaNV231cd8PhclIIBjmk4p+kDj2P4amFYtCmTeFzsdwtshCAIG2FtTo0RRq7MAasEoT0uQG5GBdvD9X1GKy9el6TqMmFxadVt1Yldj4/qtHnrBmLrvtAc79cs+aNGFygnG/QxVq7IHOdJGt2ernF/iFtdHDpQbGHaVylnz5MPy285zurrNCnveKuY+fyMDZxGy1xUBQ2VLqm/LcA6xmF0Xcq0aKaR+bBrUNd7UZzGJfYYgVWDK7Jx+5DYqLO0vk04j8O4xAbjZV7Hglwxn7dGCs5QsU7KMhkSy/lIAI/Ngfv1KLZ1tQvr5hyeHmRxDV+3hoN0qSTNuUcVwWXAOerq28o1JwVC3XVEzuQYlVg4lKLH40e03nDOOeazFa52+W4C8DmEozJzrDT4m8PWfbPRso1kNaGBY0XLlkwtwUtp7jxNPbU1xuCiocFqu2CPhNLx7dEGxCR90TJWOPGQf8k+YDV4RpNGjzrIlVnIa5rmD+/pNfTL/Fte8aIrFs+xb5B70TCbYwZHX6uYd6WxJTY+nhWIj/0+325uQX3T3RT11TrwDVlD3SOrPI0GIi3yGLpvc2qez/X6GhVfbr41yY9GqMZFz3jPLtyE9mVE9qa0IzuqUUzHlI0YQKw5lISfOA2N8RYX//5y899ktn07c//dw77vzpZnonXXLI+F/W5htG76+z2jLg2fbQzgg82myO9FP8Pw3WKcBcJr2epLJixz4xILN+1mJcE4LpmdS3nmPEzz2/bRBge+VNaeiCeb5i5JqNl4qtgCi1ggPASSz5rvFft98VlSvhdjoqzV9SfS1E2jgpoePs8b9dWMXmQc9rsFtqgS3BbdN3Ms7WM7/4Xw9qGKuKMSodAa7+dcjrYv2y7uZp4f8mV0JapJeb5pX8L5Q6FFJFdUtqPhoriY74vPI/MAkMPUKWtPu5aIymVcstzq1L2VxI+T/b51W5QwrnAPM3lu+/h9nUgs5KbEwm4syetF/IZ5+GrhuGmuXI18Ns2nJaK2uzonebGORJNAKLXHfBGlFYy1KbFw+a3WSdZporG3b1RidSgKH0yMCix62CUl4Ak5Kpj7UOIdSpFwb6D/aH+40d+3hM43+sKlDik/RnhvAO9ouaIl96GkKx/z2yQDnbhiqR3mLpORFLkAsDVr1ZCyw2etkuQiMViqpDWnWanoVS6R9ZnPdjMvohq+zrtGYXW8iTI+VqD7aIMHq5NCiGZlPlsdw1QIf7tPshgIauYKLfoo3Lo4srxx0bLdG35d675aY3oLYnprg+mfyYY4WqJUDGnkiiysgrs8Q83hAGcUsAUW8hM9QtiYz3No+aXseioDvqHurSS5mPWymtPoSlG32eo1eipcto/BAQfGQ5EtTjhchi+z8Ks95B9RVaHitAQiisVSC8x3BUIq3EC51ZEgKpIYxMyXWejtmt5kvsy/RZzZOS7ZtTDjZ3Yc3zH6J1Td5Z5hm2NcLre1NAi2VUdJ7xo73jMOz52ntxlJ7HVHkjbwZ4bjou3hTNa282RMFpULX6rrT+VQDWdEB1iGr68LdN8k7+AWzFHJrqnzhZi7OxH14+sOi+NpM1x1Gm4OG4G5HYkrqKnYujBLwIociixwtiEXbd0j0WsHQ1jogrzSNyIFson5vuWI0nx5PhGY+8QlIW8R7txW/qzLLhngvN79eH7m03gyEslZfFdkc95U4JHR2+P0xj0Y4iKBMW/lW1Im1yk6zVbJfbKqozTl9D4IMOt1gDuaY00i92Kpha+tTlMpYqFwyXO9jonQGttr4mkcULz0dYaujtz4hCH2C4yGt6jt1N3CowE+oHXFQ9gbWU2M2UW9hi0sptjJvJKghyHse09DzmD6gBBOY5A3IgVy8BEexNzR1bhkeePk4kfNdZB8sJCPKKtvophkqCjwilZBByAyGPNW3lf81fPmi028wPA0/DhUYPhu0Z+2DmQ08GU2sad/1EmBvlR3qOhtMC4KFYKwbmEwN2D8o3IL+a2x3sKCHxND42C14rDxsqyFtpndLqk3P7vDdwunS1uHn1n2u0W0VpY24snkHR/FbQHlNvL32F1vkuCHIeypcfy4SQrqDHsXPZUwZXgY+1ZoMAjFAMmWHMrCuonKiwgbWwhmGaDYQpuOagqH+kKpVa9JgN/BbYGQaJuKpXbRhH1FMSYVKLaRy/4JPF4wmQIb/dVWOnqKU/QRZbfVHa/BIAjXFs5QkeTCPMpgHFqhBgZFI2hiCMIqPu4u2RxnEd7/CUpxVGSDU56MgS+zihFJiCRHaVe7ObIRYkYkUMtFWJ6Wx6VAW/rJxpnYJ+vk2YwrsrLJiOM5u8cSiys3h448dimQjRszj3/8o46o64b3Y46KrA88aP2D+yhJo+skFdDLodxaggcBQ1jMQ5IpsIulFruB/KEZexs6KRw+AOVWu6Tk5on6O07youvfIcJ7U2GnJAe0OLCI4h80xTDJfC9cseMLLffb8id5hI23+es98japKwRPbbKu1/C8wxC2LUSPuhZ4CEu6oVVbNeGXJqDYSurIunNYPx3WVSWEFQil1pi/J+VdmpSVAj0PYkGZRtekCLP7Gd6HiZ4xGMLisADvhmjVJOZvG41KbPyPAiprHF/SFYBm+GrtDT0iJ7SQH7QpsFiDNihOohTo3bjEDWN/HHeZrIHDOiWkW4vtgZ22PR7OgsNa9+JxVqGihBgNArBa9YjiGWFBEPsoAa12wIbtqQCtdmKXCWrkkNOMXJHVeo7K4an7o3x9nWR0fwuMQwtsNRasE5vXvQ42mzTh9woggDn+7yi5veMfQWi/WVAH2OfZ7+y+JyseSfvJgl7AeD5Yj6dfI9TqRQHm0JZKsUiBlozsCxpGFejW2TblAFGMNblHxROZRMF/xpWZY+3syK9ZIpxk82U2ln+J2uUMcFSIpQ6YP6GorAtE+ibBPoJwaOFgLYYZCYUOeMkPJW4WwAJ/na1SRA8vRW+fUGiL9wwV5Mo57CSSgDi2QWigbqKHcB5F3riasP5VjoQF25ownn7h9orj6bA4BPLIq04TyUP+9Yx3b3sMnj1wZVYedswpMSaREKTBFdn3VIYYKrfHDqkfvuz5hD22J5DlUV5v8ky8MwSVW4W9g1jdsHWzQI/+qfEv49cxhGXEQXPGhq0FKOKALdwarRfoCS6P97d27/EtEi8nYhm+2hifYS8MHeYV3qxLsQLFNm7OJBJcm/STjbuumWtZdB9Uvg+TU+NqAmNlp2JiqQXmhAYhCSiHzza9vEUXyZ+8Z7X/6hgWWF7mF3hfGlcwfh2sff+/QMchQqGlu/k8yoTreKOCxUNcJ3Z87U4A4Da6WcI7k3bDcXMT1Wn1LUEPnwQrUSjcGoOr1Z6et0UaJC63RWQ1pzG22uYOkyzi357himxOTNZIfD5k+GqhdlBO3l/LBFtuVGAT4fIZcWf+7SerqJsiyspECFobFcwheMtepwojJyNc7per5paagFl+QxpxO3e9urNJWldEcws3hHuPQejh6VNimYa1uqZl7g83bMxAzusUybICGoBbhQHAHrdRgcXeuckfJEm3IJba2ORtCCaMGii2ccKVFd4pUGuWfbFMDMKVw7m0dia9EgFBOLUQPREG6RLSyFrhoFxa6iYA3NspwNxmCXyVGwSwcOw+VkVEFBTn1x0+b49KZs5UPXUxg8lFCSurb6vvEdfNiw/oEXixlCuyXtabh2LBdb0resamQquumpNKckwZxPIc0Lkbnyoc229/tke/MEah0D7CAo6tcDFiYFtle04Z/ZXHhPkFkrRCRR9kx62hYqmF6zFZocu7en2dCXltuSJznG2ihzG2/uNCzsBn7cTbFqXe82DDkoF1PIc9hMrXopxmBRg6AKts+TsZ0mObbiBCfn22wAEfNXekSPtSGw/cWYGakyLxLuCoaNv4PNBh/hiby5m+FsP22y2yA1W3o9TT8gSr3Hq4r8/zlVD8/E1tNs9FEIZlEbozrRrL9jMu23/gFuuobM/ATgwcjnM9WXYJXvXfhoSOemKpIIssksHso4vUuPYxQLsXA7SPfdlvm8flbgYavUB7k8Q0cJnx3gQw1WDU7kabKb7tN9/gkTRaRTg51MBaKtTGxSDcEeLLbIMRuxgKSTziqPgZG42qyfJ81kCB2eWVAyt000gU3Acz/l/gFtRz4MQpeDAY9+3Q5mbXuKHVvzQpf4CVHeNxX8bBykvP9LLz8i0qkigD81cEmS8Ffvd5tEI60QrimanXP4fuPLl+Q+Qrem4ZQ3Y118BBWSa3GVr13hX+vh1QbrXl3plMF6cl9H728HWZvdlgK/3nmotF4Ios9NQEWSHpju1LXX25oSioxQFlpRNBtmb1Y1nHb51jMTmsaOrqS9smc7nYtytEUK412ntfvNroP28Nf0sMpUlMunB23C461NpKUicCVG6OnaT9wZ+EHMnsdxsG7tL68xw8fHdYro7yrCryFErTIoN5/hvesDIXQNhml7IQGR2WW6q2S3HTOLNJtHcTzh9MhUvQTarH+T5IVDAEtmvcTC9hXPxRRwUqz2+vgRsabKHlNv9g9a+6rMT3LIRCi0073VzLEIul84RRzmcyUnGAFsZRgc3Ze/ZD+oahUDjldYel7nf1j+b46ML+NRl7vSevOo2O69p7Xye8U2VUYhEvUPav3nwtOD8DX2bfTwGlJz4otwNfZqM/swo1WQN53ckUWF1MAfI7uCR3OH7E7ZeClcJ8ttGN+0QRYrmlpmFyh/uomh6Ng65R1N3+jTF4Ednh8rHq2rn7VfNw9/tsTkgWYmUs+qX/ndMOiwMjy6tOw8cfo+y2Jg8q8RYS893CCSMGu1oHutLbj8CFSKvFpk65tbX5skyI5bbnj20Cc5sXosGHffsiC5ztS7Rt3SPxiA6GsNgiDs/dyhuRAi0fxBs+vPV5B8YvtCIQs7LIovSgru5wo2081DmKKS19VgkVZoeVww7dNKtJZ2XIrA/LZCpr4aZ5+8lus0CocroiNLlJeHcFVG6PvXV66BoBwMzb+kIm9jL/gTgxZL9bYjuIsc1eynCOSq0s4/tkhQpZ7imofGuk/SQv6vVZXnoedfdoHORYUXcaob3MN0nMo+g/LiX84hsf1o/4nh2sVnhR5tZC5vP+LoqtaFC2CCAbFI+rcEgqTyMdtEUeRf9xMekgJIC85aMCiy1Kk92Z2510Hy2M8k57jq3w/qvFeUCCd8LcSUDzyWZzW1akYXFzO3y3xyabSajcHjvNggbibUr2OstOZ0X+yspVT82qot4Xeb0B9VRfsgvBBArF0q49vGbpPi+hpIhogubTqGCvsAx5Zn+FeCKzjaqAAGYbxeOqDiWVp9GJ26fBnjd3T+U9XUhq2jB8H4FpptNeViT1phET2hh0H2pUYIlPDMBgPi93LBpm59XmH299CEJSPqHU5uCrSWstQQ0UW87LRRVVtYCXK7LvL4xWLLVwITa5xGHEQqE13iZHudQ/KQOy57ijuihQFj8BjyeCEDYtNPXOsVLmMbMl9n2+jB7b9QhyL8ihbCL9wBuYzGdbvq6vq7yK0tMsTnHHIPbmIRxbOH7UtdBD2LdwSer3zz+oxgJDeraoHBsMadtiqxIUY+MhHFtQjIWHcGwB1xVlD4Zw1E9YzyfExozSE4RAkhmAh2gbJKYBeIi2QTIbgFt4UpsqnGU6fLXkD5jrXDgNzobOFdn2jogx1L/muzm2c3RTZyu0gu5e82U2WB+iYnWWJ1lVfkcFwnPLB+BIQCzWuTsU/8jr4XKDdJ+nhvRoUby0LAGxX71l4VxQuUUwz81NkiZAMsdRgYNFvpFY5Bvr8CWyL8BKF298sTo4wiwCmRhqSIv+41pAYHT/1Q6TaIIOXy0xAWN2G+GnqPyBVmpqymDs+nx0f/9W7HHz1Q7T8eMmKWjQy6c84xNggACu+P8LRQCV+XI3Dn6XFCiu3qHrhI+XkwHZuKD6agcxXUE+5CngjpJB+bQEcZAcyqmlwyj7IW61QABn/KKwggBu+E+P5KhJmRPW9jUzKea+3An76XXEu0f5Qvt1gdokbbwmvEKMISwkrcY2Y5H8ScWU3s6IYiihowrOvzWRSdWQ/i2eo1LIxqCDtdGOG5IGR0FPGMKnBWhEciirSIjeylMMSAFmE2RexHdRiaReWBDAZl+VwHHiowJ7j1+z84L9fV2ZPVay4cIivamrZo1WeumMK9kc+ITJhLwLxzLsNuocraMkE7LNSkDM2/gQkZt07Wb9c171ySTH7SjAtuY4qNtwfy3x3ulDUlb+b7sAKF0eeDFDM83hUdgnbKmOAw8nLJcKZ/FbiLneJzd0/xSQuQCULsxlhmYa5ura5rGw3y00aIlW35PqDmQyodAOL/ACKPP5L8C4YXjVgz9nu/TbmmMMtwAPs8mh7LkfOoPjyyx2B4C31t5Le1p2PaBJICMgqwgAYD92vDHdQHslqNzG8omTDbmSL9qUXJEDTuDGEl9mYRejjFj9ounLfLfFBnRwVGDhIURlKTwk0H+04aaB7NT4g1KuCQDPWKv2GiNA+JHjJXRF3QnDkEiDktChoWh+e/IsYKaHcLkUSBZUmjwBPBkWSx0wg+e+YqkNJWX9de2rvJ+ufQQPnB2Olbs9ULO8goOWgLi2AZJBAmJhMmiPSX2PR6fI5dylPQIyAnBFNgtVV1Vq9gAANpGyMcqGpFJiyjKh2KLvWH9+BzK6s98tQiDpy8NkleGCH5nv1vr1iNx4hTRsU7BdyzM2RDx36D0a1+UZrjvl8uy/lNI+j4Pyc2u1SoMO8+4gCIykZ4ufsaXIemjD+I1EjC5uIyMs03Bq2FjvZgicVmq/2WI5xCWZkP5qXGTnd4J28+z3+fdyOydB5BSpSW3kIzUdFpdHtqRVt1uTXxZR/AMPDDq05MsssJIwRMhOGRVYniwi+AiUL7M6J6RPtIBohcK/gPT4OytYTB5SNKfLom8TOAfvvjs4QGDZtPYf70yW4nNU1UVGHlVAvkl3RqiczBZl/YnYKNAlt9AMFNaQCuf3OkdRmWcnedHMFu9r5wpt8NJpR3Tvzrs4hEJnvPJIDiWg/bzB6RzFUhtOjW5umo0vx6zDdwuvz2qdZGCI37jEhtKM+MJXByUguxnas9iin9M/j7DyDbHwj7E5Lf46FNutuc+iojVdxJuubImtfw7COC6xMXYGGkNH0lD5Ypv2LX9nsBsVZmFUkEcohKTYMMQSq+1e3wFXs7wUnoDOQeMZ4JhG5ZF/Of9tZBeFsM2vtFGPQHSdolZVwLjlUDb9vowejx+RQIZRgdWh5RGWndu8eBLyAY6LHFTflr5ZJ6et7YO126JYArxcBuMMoWJmfa1MaF2wDCCAOfXY/hUwP+ldzNsU1wW5QNleNwh1agZhdTs5M8Q0jdzxzYv7Z7F8H+BvzXVhuS0Am82m15/iFH1E2a1wO5stsMR3hookF8JluCLLMyham08JwhZYuc0CP/5ib+EoTrKC3Hg7zZIqiVJQwPmyZyzndAJwwcf81k/EGUQO0q2sPY1gM02C+wSxeCnvEHyr3N7bvMvMSTAHY1Ca8cSLSWEMEzlt6c3g9ikkTh2Pi+bcTRxnxKHA9af/uDUs5K3X3PTZjHoMN/UR3aNUCL5lvlt5zYsKjK0al5hjJK/YgQhHBRYL9wZ+ImXj8kRKWC8+HonwQG7/0WZLc4OKAhUCrlHBbnrEpVxSkBPOLOYOAJjPNuslfe33Q1TyJjtbsDUqiiYaZ3NzBEh6zqJzzX2uxjHRWse0Kd6rEkuXEvVQL+wEe8dq10y7s4LeNmn1vx/Hj3E5sLsOwXYfxp8U+VrG3XyZDWfKcI5LrGQ7yHtNAV5ZK89RBJy/RZYnYq3b4fCpSUslXK3ii51w9zeJpegZiGesMfq8nZ7bwA6NywZQXnciHwWcVt8pnX4oxxnkyNu6g8qL+A6t6hRdRuUPz2gvBpNLpJey+jRc47+5P8BcLryqTT/ZKJg8O37cEEYV0xRzZRbKX0hha5u+1tZxoVi+N1+y46LgFf+owGLW8CJ2XovqmP1u4RWIaLRoUQn4xiV2GI+zFYiv+27Zv5q+1gv3kCmz7KM4I8xnmyX4Q7Ja8a8MD1+tovtuCaufoSIGDt65Qnu8oHdFKLTwP+QP31AhSi37fWs0/UGchnjYvEfj5BeW1p1GwTdt8ziGr7aYxAWD/W6/xz7PU2k2967MRhBPV6lwcth82xo2/FoEYcMejQMbKur+tdjwIq25vKDNlyWOq2WPG6gfNVgqOR7KUJHEgcKGeWwuyfK0KLads/8DPTVvSI4wDV+tMAlIbOoDKR+t0z3auqwW4uPLO7RG36IiIUa9HxOPUDlwsKb+NOxLG+V2Sc2nOTeRfyGGa98C9fIzkJ8uDga43rZ6FoQzTcuzzIsyBTfw7HcLbCSoUDyzZT6b4/ogPs/9wfpt7vw2P0ti8iAAcJzPFi15XeFDtU4P85WwPrLfrU9ruyQUn1H1kBc/wINbAcYq+B0L3BOVlu65SfG6HQxj3crxY3yH7TtEE/2rG5OBbo1qazvlG2/ejc3lXoe06rYqOdUbqm5vp4r5HR2SOxJh/5jjQuE1oFGR7X7/JC/WUVUl/GMMYqmFIvR8glsqoPV1mpR3/OrBfF5Sse5CoM67nDyrcZyt8Ixy88IVbY0Ko2zSfgpgpLVgrraatPq2b2UDO2l2w7I/jOIfpxnuV/wjXIiWBKkDRxljmoa5guWTCJj/IHDs/a6FSXyKsvomovuE4hKt8Trk68eDMDqwqhmabTXpviXkvSf+DtjwdQ6zYakdQHsXPww38dhcNgRaFHsu2jouanV5GCbikDmFfGow7Flo61joHJGpWrVT53sjmcXldB9ZjWAa/uktojcSS+mNE7a3EmxW71nvHD8dFXlZXqA0DcJRPDaXhU2L4vly1VLLUpNNoHmD1XNRYlG5LEnq+hNNPduo7OFaKZDdLUDpcyxC4dawxz9qVKMVfWjsoKqi+M4/FwaI0oFdDPFMwzZM4zwirsjOmRDdIuKGFllEKLRhcd5asrWUThIxnq37ZrE+Co/P2D474289fkrWSAyhHr5uo+AFEzc/IZtvMU7yIuEzYQ5f7S6GidfBbDGITDd8tblOxl8is6st9qL7ZnGIhjbpE9+R/qM1HrFLowILH+MR51k8sql9GHOOSfph/mt55OSf6wj9suTx1wWW6UuaK42L7+g/2+ECusZ8tjhKoat2DL5EzpdZ9XBFvKxRmj4JnWRKtkbJs0P10/IsJgc1r64+0cGc+Kyt9YO27cZa1ESjArsYJjGEyWr1ygv+ggv9YnFkXaIiEwY0fLUx/MpSzJkzfLW9M3ZR8vM1fLYa3zt0E9VphbXaCnNjEqWlMFgIZGvk9ihab6Lk1vMUtMPidAIgq7qtbtvnvMr6BussdVLa3IwLdEg6RuZyPqrDsK2sje3NZv1sbqXzDAAU76LYhLsSNI3xN1XEnLtRKcM4eKveQI4VoNgF91s17rc+uH9W4/5ZjnshVfcZPZQfUVWhIlwQE4zTQfGZIppI/4Gti7mnVHDzGv12CThm3GzvRkTfJxSVdYGavPS+iz6DymnJV9bf1gV/ioSk58StL0S4J1Z+uZ07gG7n/12Cmyy9FTKPzZ0hFSj2PPnMefJ0vckL8q7RTeJ7d3aEyoEbNfW3lRVP8hRPqYiH/W4bdQ9lKB+X2DqzAiRA+pFw19qbLxbHOtEP/lCHfrE7mSUUOMqzm+S2LoCTYwmIzQVFgqy7tsHdSxwVWeBMEd45ceTrP1rMQZNeDLdOEowJxpdQujVq5uIpi8NcyRkQudzIUdWeyO8f7ELORV4XMRLyQjCfl7rcQ+/rPlYiulGB7UjFhM7sd9sbIqfCiwrDZ1tcF1Uhuf7YldhiPMzzFMLXfLexi7IY3OWNCrZGLRw/kiX/HdqkeYBnh3hsLieDWhTTaInW6gFuRN1YO678TZpQJsNpSW/acqw4fLV1X/yTt0CYzxY2ej+7kJkllu72WaZvBo4PVbW5LKKsXCc0eydEMxmMXyv6NmxNx2ZrKAYI8mW2zn34JMT9GITWBM9CxiVLH0IQfkzu0Sch78GowEp+hEP37tuWrVlBdswjVM6r1V98x0yEl/zColthRStK9qjQ1sUk9tItIB7/eZ/g0Ulj7oFym4W2VV8tK3DrLVe4gO/Ae9+qmH08sYI1zny2miOiVwWXAvvdfsYbR4QYDQ6V2wSllnVanWY3Qnzr8N0c25ebmxJxS033zfJMGjiJtjq5j6r47iL5k+Nh5rPFDGBxounSxnTvvy69fB7l6w3Nx6+yIqRADsbzQRHfCWeJYul0fq2pl+yDsszjhLr8xKtfqGhNxyZt7hWbohjTU3HTS1NTuNnFwbPggL2wEtlW0dxV4wQBrAWjtV5ADrEsIXPfK+8OX0bFLYI240YdZnFZdva31yA/mLPMxV1C/2xuwl1h3VoVCXmB/IgIexNRrnBVGtQWHJSjOg2gkAkNmAJ9W558wzUQgGsMuuzJOQ315maajmGvGF2tSpQnQosZ8RqY7sVDPW1FrJ7T3yMMMPFA5/wmusWz2EQfJikxXvsHKQ1mm68im3KbuR7j9KQphyzktHOo/RjTumPY3F4lZD5fnJaf6zT9/eVNlJa8uakbvTfzvEtKajFeHWw2aUJiNds0N5pFRV2PZ6MOukuhY8BOqgY856pHHYCblN30XDdaYs2tT8QhnXWJKqwYYqglY4czON+EEZk77FvNC30n/TihRTM3I3TNtv9fRrfq7QkELkmANMCYbERExL67DyeCGncuyGxjTItZEsZbUlkNmR1huQWF0W+jDflctprn6CEqVmd5klXlhwT3A68/X0u0+p5Ud23MoCq7lbaymM9KqGLAF9qGPGdgjCsAn+g7vI3mp44M4RROtwm32bsIdUJsXjiknnzEYwupcXjc28hA+vHrWajztZIYrijJUMGD9M7c9kv/d9l9aLP4kGPgtBzqkfOedUQJUm6imLpqVugkKcqKcNp1VKIG5OWL7pCkO3ZrPWt/pEdp8wJyB/ApypIbVFaX+Q+U/f7y7U9v3r58QR8xJTfX0puXLx7XaVb+GtNpjLIsr+jQf395V1WbX1+/LmmL5at1Ehd5md9Ur+J8/Tpa5a8xrp9fv3nzGq3Wr/nqLVojLD/9e4elLFej/DLMoXEXKkvehB/z1G//gQRm6JjkHN28kPHTb6/5ir8BPEna/v1lQkhKxZk+xUUzHjYnpwQK0V6+fEHYjhwB9qz3WomePdJsmsnuoyK+i4r/to4e/zuLryrE94KE3mZxWq/QaXaRYLTRpkN6TQ6aLLt2WnYhNbigQjF9G9kd3RCfE2Ccl0mVhqFYc/c1AKJPqIraixVlMISjTHCBcIajnXCV1p07zlGGFdVB+T1ZkaXNA1OD4Z95FmaMDbrvRbRpH96R9M0c18Vd/jCaA/dRHubECPKUyz6bFqPmLHHQ4ZB9sz3F2VNNtdaPHmFP3c7qfkjrv3zxKXr8iLLb6u73l3/76SdrpOOrVKZTajwL2BqqhAsCz3cG3jrMQPuwn0YSzKyD7sZw8HmkDxwlf6LelH4mMzrcHWEa4Q3TX0/xYvP4+8v/h1b69cXpf14J9LgisSV5na3+7QWVpV9fvHnx/1p3h33aNniH/ubSIfqw1fDmKs/7YXr2M+mZpyLrezpVJ98G66SzxJuLa8tHz0RKtXr3jctctDQ6qlPysIpGr1uj/5olf9ToAuXNe3Uq5LZ24Uka3Z6ucde7iFwl+l9+ssV/XqU+FmJAM595XM4dycQmTiPTzWW1c1QCHqydlTuP5aiv2evPnxyWn46ekxheHfKABthpSRL8nqX1bZJ5bPxOy8u8juVs77Et4uMLnwmnGnnEPD1sY4b75Rdr1P1+1A+x8VzLDyqf1Tx7z8tJgVDn5fdZaC6jx+NHtN54+aMwknbBam7lgeuViRLp8lr5eHQbYaD844HHTaR8lFyeps+E4RdfgkNr1j6ZUABnaxDzkPhXv2QfcnKx7daLzw/SNH94X6Oywuv3t7zyQuZmtUI+oaggR4GIZito8JDni6uEzKsdvY+zVSBMznsEKx1wkJUP/NH5zmoCMiB7LdDU2hIN8LleX6Piyw2RjdKHqSfe0vWRXu0RzvNgIPYVXzsmGmp6MdLpZhQaY7aVM9svHWw2RX7vtxCMk3fK9ZuZ+2f0RrwVMms2fWb82SSGbRqqqRctoShvEiLstvPQJwxRusisWa5NPRsWqSzmIRTek7xYR5XNAZEc10WUVqH7ebBaJ9lRvl4z5+Z+8S1lkD3Zwc1NkiaYy/1I578je4fo9eURCrn+dtDQ7Y6ve89lok2fsst+LPQxKiuzdeaNPfKgKwTp6cf8NslCmdQYH+UwrHsNUBr1Ebi7ZWc5CAhkBoTJCKFITLvuiBjM+2O8LINXS3d2VaahpEZbAFMmDYYMXIOdMJHD3igLE9jXXpV2sLK7il4ygtEjGsibxQ5OI666T0+OmCAxL4K28vQmJLK3QZD9M9mc5WUVpdAZr5tH6y7PULNNDoLvJHoMiM1j/TPf1EB5GnZWe04SuUD9jGW7tHo7LMsgRx8PefPCx2k5QcDD5V2BkDn+n23xYxFBRRJzuJ28rU06wcv8W+RlPS8Y+LCEs3acv+SvIvtO8bqBI/xD8cjpbYapd3RHrppNwiGsYfJMGGQ6S3HBten6ukD3SQQxqO/2exeiwQ7T/JbYhM+ERRc/fja7fWTmzDC5umVuN7V+Sq/4xu7YosV1xDrdXLTw57wKjXLImOG50mznQbTqGp5qsd66G3m+nQ0YtTvHNvEMSruzs2q2HQ1pwfd0psBdoJc16F0GgtUP47ekTDA0VvDJfbJqXyx1541JjOKLO/rQRFhJO8HQoXEGP+DqGKd9+dhvqsNFQnU4Qu0u9lp6ZHl0cb3Y0EYPQQwQ8jhfdntRrwNZH0HwdcgusZWZcoP17F8olL2/5yDeljszFz/q4CISZfVNFJNrUgVeYSrYpezbyvsqUW8ZHXCelu+Tm+ooKrz2jB0O//X5HP1RJwX6Ut2h4myUkdA1DwLFNyz12jNve5VTk61elcRk6T9Yrbgmvbp/Wr7LH7I0j/y29C0Ov6n5mqWNEHbovEb2qTt4+XIj4HOKeGyRHD9ukuYdxnfRkwyjkeOvRUhDBihCf+7+EJUXEUmxH2JWx5gcjjK5+j5nmXhgJJDs4LZAiLXdXMY1QnSJHkNFOp2juC4Kz3OcHsnRU5yiRm346TsW3xkqktxTTHuMdAmnaL0E65Sef/XvsPjoslD3iLCSpVnJorTD1vjV+700ipN1lJKEXfhXSTNvvfk73pWSi6h4mXToepAwudPyuPQiIZOzxY9JsMFCXI/ZPRYxjKw5VvLcHFV5/OMfddRu8D00ebMnovgO7qME101SBqeHUxvso9PqlWTBxvsxf2jG2sam+U0DtuGTmye6jz7Ji65/hwhvi3zQHkbxD5ocieTX84zyJFs0gu+0oSHeIvSbSy+Tgi5feGaSdb0OMTENvugxFD46cLRqUSUovCmK2ZwAH9ZPh3VV5bIr1qYiQ6C/J+VdmpSVP8JWllOE+RIr5pHPw8mLiu1tiiqJvXwxIwTBl44v6WraBtptxhE5U5uqjYsNxhOlzgMxOv5g2uiPQi6TdYhDDBZ3ezQSCHPnajrOKlSU3rzYaq8RVjQxA7UabtY28X7hMkGN7HrpfLx4orI6qKoiua4rdJSvr5OM7ngmZVbc/+4hgLJ9CMBnFN9Rcns3nfiOtynB0X9PVhNi/zAtbfpVKbTO6RGHVTihTgzCxIpMfN1mW24cgiNP7lHxRGbV3vUyru3jeOns0q9Zwp9jGvRjXNunH4dRidrl1dtR0OP6hKKyLhDpndJUts/g1TdxsGbjP0IvE30z5Me4KQeP5GGdrVLU5IYF3GK+RwEN+jNUnFZoHcJNM0JIyBAS38Vd3nh+sNaeIJyyW92fSfyENqrAJT9YRyN/v/jXkkxrjAfnea7ePzolYAtuOHRNuWuQHU5P0p5xlUd5vckz9lKA005ewBIqIrabJHp8TFdBP0Yd8JCl28Kvbn69Z5+TW4uURB7ZIjbilsBRLod5hS2w4DFS5KGR0ILSsV2YQKl9ONIo3DDMmc1ZQgNMHFIcdRV9DHwSrXaR/Il8RjAKziov8wu8fYwrHrPbYygNji/jU4RQ+XOoDX8eZbcan70DhwSMKQzrk9rCyK2d8FmEctBss+/jJqrT6luCHj653es2j2JvVNczMYba0RwmWTQkucVUu6Yf3FYuPIEEj0Yt2Us/ykny9ExnZf3sEnL4GT34SPBpeVlEWZnwcUYGS2EvB1cMEq8XKdSS5d0l/ZUw2xshz0ykwCscJkZRV9Hr9t10Ntk23NXszIl2t79+Pqkeu5E5uO77mr4zx5P2vE5R4OcLLzZocgdVm2YDvqttu+p04XwhkJ2jssJ2O7U92UzvUqxmjq8O6Zk0otxpqhjE0RNhhyYmLzTyjsKSjZIn9tbI96Lw8WNVROTl1SntSvYA7pmoNK1D7Bd7K/AoT/PiA3oEXwDxRd4uXs3zMIHP9yZeGFvZbw6kyGnUM+Ghha2p9oDPtRNcda+uBApkjqc8XZYfds1x8djQuTXBveMkxWzeh3x5eZQ+JCt0eVevrzMmU6ILovYW+PLerWfmfXJXyT2DNPzyTDT0MD5X/djU9VKOPWk9LwJ0aKh54YfrtMRKtTlPsBEgW/Z6ZqezC6/3knMxkwRffU2/BxfKE6zm6uGy7vyq15YD2avmey4MwYUsRe37MK79l+HGZ8iGk4SqBI9UYOi+j9UIG6uxj6/Q9m734iv24Qd/rQ0gvep3k8SUkP0O45ksUQtbSjBtG53gkH9Eic1vg0oUYbPv97xz0IRndUfn/tHpU9pkKoI+EwGAhxiK97bmHchFGOWZsMjOzEKrVC6j22dMecsNlC3xvkVFEmXg/e9nQtQJshVOkUdwngyIk97pd78lb4Ld+ZK8UToC5zvyz/ay7EFZJrcZlsBucz5Btp39HXDOf+n/gOfCO5zhVPk/12FezguWJozuab7U1ZcbipIOcoqHZFh+eCZr6BShUQq3ZpjYpS2Ki4JEvb0EMt1RK2/aPRNe9FVw3f89Xa4+RTSic9CAV+wse11u4Nty7nWoLTbJe4E/MXk4vZPCNsmafdYsZveRVUWeEkx+ZzJSMZ2BT94Gv3Hy3ER4kgvYAd0WXgduvmq6CRV+HhMtGaKzFgRpJSsMqceX41izB6HTvLj4o44KVJ7fXofuZ7N1Xf0LTxObmjx8Gjy6CZ+hIcdYt0mWmSAsrV9yxL7ThvxX2o9J9iPQQ1D2mzzz6yrdcwHPQ692w3lfJ31DdZb8UaOEorxJCD+GPBX/WvYPHXwtvAK9ATR+78u2+EJeCid2KGrycoWKuAdvgjshO37EfStDRQPtL5Mvc5m8z977TFTS0pEVymuTZgE78iuuJgHVo9ohvNE+YwmZfNqYpbEiKZ/RXb7n9DIxvUcWBhXJHRcGU5BwwO1M7/hXer95O971BU7U/5px2cbqmtiRRRalB3V1R1RkE810jmJMsGeiwrtF2X0591Thx2vmWqy31U9m65TZ4AVE27oVAmP/QnjrMv+BwkgIRXcQx6gswyHFf97jXXPhlTnGWOhO8qJen5GnZp6HhF3mmyS2F6+2mt/lx6WF2+hpRbM99NnBaoXXzvBZaXftEgKVD8odz0RA6IDsWbSttuMCQubR38XcJlJVm0UOESifG03s9bjnN9/3vT9GZUV64emFb7FIptwRG03u5LkT2k0N9JyUz/sirzeOGqitG/xWh//TGYE3X5/bVcdLlkMoFCJ7kFG1VyuTxOHtpnqiYvlMdNROqIfnxm4BvXjGnNsQ73kwLR0LfEXHzbNB8KlP85c7EFts/9Bmxm33xg75urj6fieMbeJX594ICHwOCWnNC9xWzffEcVghcLWJdwOianL4Bk7q3HHnUV0UKIufoHezHBE3CM+xkjE8fP27s1ReRo/tquS/w/4WSe4buiszvGmvsCykp1mc4q5OFss3auz4cZ7GLkljfSLzmUY4anSekba6YZ4Rto3NOjLckIWw2jc2UmNY8SdkbYjSE4Smpqm85akJLG95amq3+MMkZad8Mjkj+qQ4Nm+Fqo7JmsCWeo2tndXE7ySco4eoWJ3leIErv6MCYdbyCx05ukPxj7wewqtD7xqFBoJdiu2MAEmMkm2Qyc1NkibeifB6q38TZIw0hoZsY8h7FgXCeuQIz//YTnGadoyF1A4zEaRLwQxTYXyeqQ7LH2glI513T4/u798GQ3b8uEkKunP6lGdDnoeAeP8LRWHGzvLluwQrt+oduh4eWHe7R9KjOYjpevAhT1eB5kpEHpARGOSHUfYj2FaKwxtMxFi8p0ehUbbP7oRGe3odBVqQWg1NjYI2/i+MTNTY2CuSP5uXnUncfBSPk9pNgj4Yu8kaOEclc0ffUxttSB6V8MQREQfsNd539jZR+K6f1aRuiUK7U8+iJFQkb7dTbLYzYWjaoiR7FSyEm7pxGU7i65o6W+r2Hmiw24VztI6SjMlk6ZAP6UNEbkq1m9vPedXn/5vgqKTbFX4tsW3/IcHT9WxeTFj84UBa1b71tppfQJa7sBizzvvkhhr7z5B1uqHZT95Q02v+vpZo9T2p7hxZiKvu3ZXRo3LB3S1zMuszYdDOnGFm2emdIRkenwPDjtT+h0UTu/lOy66rNBle5JmioUOGt2abgBuGczzYDbkbHMxS6zGGuzNygTJiV4fqYYMuXPc+obJkEoJ7J6LqZoTaZp6u4RmUXy/Yz0T79eMJGseyoLl2tuyV9hD3wEkOSnoXfOrjxr6hyU8X5xjNLCOZ+jS02y816/XUJBu3NjXtJjuyC39U1+Wn8b5nfVp2qIIYRh8xi2dDVh+vJ8eJ1v8+bQpt+vSm46vmUtV+RC5ihuFRu2Uf2yjPJfHLggs0paKOHWwSuV3m3QnJthuPrHfzeXl5Fo86bojqFbxKMRxGaZQNWXiczLdy8qiakJuwsIcBrP/jytPbdmXjPDF/Bugu2dAj1OcheQtq8ssiin8k2W3AM0Aa8zatUUIP8lCok8buPYtA6OZYhToBeEZejH5ITvc7mpoBzqdEv/Hk3gML26Oqi4wkfkfPJo9JgOtSgSZucfsnhN/pHEVlnp3kRcMrYYz0luMQ3f8a7PddkJqGIFjdM+LywHk+hxPd3JCNTxh0B6t1kkkiwfi8Y9bZZ0aKIsStsG2JNrFYIHMa6nMUFc9qkfTXlmdR0RoOXp6nxi/kdszK1vU5WmUn2f94dXH9v/Cxx3SXJbB0ooLkqg+XG3ea1XPn1Jxw0eWZ6Dno6NzyQVZgY7qNTzDRrSyBb4U4BM7T8jJ6PH5EzEhd0GAkR3g6b/PiyTNwZb5npqwpZfvwo7toPqf3hYTBOSyaIopps125qIz9CzxhJdDC1RHXBbno1cZ9P6+jFn509tIjYggem72Vh2/jUT8Tdjh6ilM0fsTbaQYImjNUJLk8qMBs4ScefIrN6zTO9IWAiVZq0NEv3Mmx7UaWVEn0v9u7tt64cSX9VwbzuFicbGZxgMUiZwHbcSYGkonHdjLYfRGUbrotRC31SuokPsD+96WoGy/Fq0jdkpeZuFksVhU/8VqsSh1vbNjai3/SQCyOf3qXHzbypVEaAYtQgx4UGKw7ULDpU9QlQrL+dSOwbN4etjkzlIvYlw6LWO3K2CXQ43VWE1uMpcZdvJ3RBmvyDn1F6dhAcXlRmXqLGHGsMwl5fQNwMomi/5tDFP2A46PZc+YD8pUuESMVFQUqfPGb5azSKOdiUd87ZbtxJ7FNIsi3cSmEJOE29Z5cikh4X/rR/UbGIFolr+9DZl+7QAkerDc6o+N9T7HouS2I13k3ZG8EmOOvMt8U+dEdhmztkfk23MWg646LkxsoW4fHbDvlHYpH3my0e/jL5yZyjCdm/RvGpbuf9xHjNjIKOAd19hNb2sOJULALpPvdE9qfU/QQl1820tvanejfHXaiF/h7UO88/u6SvyvPrr+faogBHm/8ltyaPTm7EJiazBY1Pv6Paf8/PO3eDVr/A08Fd+csaquPyhiOsXX6kF0XxbhBvBXJNe24TCOHzWKdZYUcebvK0jMg/7rORkuDWfiX5aWjZc4kfaSH/SURiIaNt6/ypnyb7PfIIrAUdGOcH+pR4xYVO2o94eBh13GSnNSM1vYu//YJFfTwVuTfvna/SIb+JmxaPXL4Os9NN5X4tlFw3Lam4RHEn6HbatzlqYvLBlN71MLrBq/c0hCrpo/FT0BNCKj79HzwztTHXa9LgG7z8Fl1/ya7rXld+sAaVqFJkuYbFJixd55MILdxZxvWx1nGYHt4Qkf0KS6SmtVGkEZ0sulOo1SSlgOcCU8QIfy1ljXXcGAhnDcCkiATFnD9Nn4SLFPr63CAS+3cBl03jsXwWzo1qrftw7v8kN8muzoC9jJ8ud9Wx/Qy31Pz17j71eYGsnsc/geqvuXFF999c1skx7h4Jp9Ol8XM5QEQxGXkYyTC8vo71jI7IBIye6x8MDMLMc2d71vuP8pI6HCto0rCx/K2d28OmYavHS7e5TUDC6OY+5u8yYsj7jIqarkn9s6pXoHP8/w5TcqnOXz4vV58ARO0z1j0r/M6/vx1tsedOXYKtFuDvY/J09SNDEBLP4UItp6+jHdfbjLMf/dli85BHp6Tz/toeXYvpCku/d/H2fkxJkvt4gEd8Zi9mSOnIMPBp6TOFyImMxvNOPCjt+617c8+3m4ft8Pezy7ebhffoZRYtenpjfRwP12/9LJa+G0Ml9DDcJGX5T1K05896KcHzQdHOoP1VsxO6yRPMqeM+WX8qkcRld0yqJhxn/15Rme0J8lJLqoq3j1t6GE2pZv9BoOpPM6zG6sVH1B95EX3rFv0L8186nIV8CZx8SZpao3xcaOj0mNdPidZXDw7HfZrv0iXJ5Lv8RYQdvS0YuzyJW7k+7stkrwYGdOrfubh3ee4ZmpwKG/vF5x7F/UhDyHoHTqlz3bSWrANIfGVkHR6LMfL3c43S5M3PC4jdH0v6udW1OdR/z0eFh6KZGSUEczEy7vVZgmzc0ySytYeN92jbF8f+cVp2neaRw9JWtKNzBNgajx2mv27/TVmu83Urw1Y3qYuGd7lvc0Lmb+52c1biXvBUlnDRWdZaiNbuDBuvG7uy9T8MwHVfo0e43Na4cGNIBDXCvDdXcXHU5wctnJ3BH0Wjq6T8KTnxsxoppv+Vtv56t/8kqh5JvKjHSy7bMzwwq2ZBJs3pGJE97FxSxa/jPPhYa9YL031cfhaO4l8hqOsl8Dphp2xB16/eeT175a8jAeSP9C38h2qP9wNejzAynkNjCJZjBo9Rv1WpoJwzdYian012HeYI9dP4wcBv/tBwB3Ft9l+8+dk+h7F5blAbaqrjXwfuvnWJQBd2PB2dzUuQrubhrprbDH0Gn8uWbmhYfYnjCaF0c3xhDf/uM3HZDNvxIJg6E2e1lmAQ7AeOmWsn+z4p0RfktMYER7iL2hM/XppWte+yrPH5HAuYuhC2vFVTno+Zp1ztReOKcL7hdMoczeRerBEdawe+wUMXz/Ei5j752z3A/ikm1h7sER0+dxwGSz+r7/clB/JFuA/f3nA8HE5v8/PxQ6B75WtxWt4qcWjxy2Hh0Aqv/yx5nwpymuqKlB19BBN3vR9r8Lo+pu7rkDV8asl0sToAKqAEYmdbkbFtml43FeFt1GcMLzMc9lVgNGxHe6jwK7819/rhdprdErzLWWwaFeeTq9AHpV+QPMtFT2sw25K8k5vN4ZHc8LyP8moFcoAuPHrU6NrQpen0Ca3hA58DV7U2z+pr6rTQxFn5TEhAQLHWxXiOHYJ3myYbV3ozX0ljK5PXMxL2BvFs3UV3ce1RQ3Y5Ct6Tz2gdrx/trrBtpxrfh4KzHkoUH+G9b9azX2D2dyf3Ho0LvKvCbZKSI/1m7IdoVqIjrmM9HBoMt8uHsQNxouv1TH+sx5KfR3CdNhojndoL+yRGTLKc1rdZI+CW6kTuw+PjyUa5RBF7qXHMLiMq93TffLPUTP5Lf4ISVSnRdzV1wFAScxsuyWAm58pXvVeYHZj7yhtT/jM3yuhol2uNTEn6QCZLhMuzy8SZ2CwHt0uUEc/a4MNW+7kRBZeXvb3OtmJw1UPcqRap27GQ3TztOuq/rbcMpSyjIw7vWnQqb+BFi0nO57ByDR0gyqW3dzXDBNGqgFRl97KoW87Fqa92jbl1KtMW26fy9iepMW3k2CoGaInXyclmfy6EAsuXdnxMP5A27ac+pJpzM6SVNVxXyUtvyWchqohe/PW/YG2bWe2Ta21L2nxrU9o25oherLl3v7vIXa6nJT3jYocN+a2VprWlFIBOvmdZGgqh5wzx66FbSfO0WvgBcyey1/z3uZp+imvYyPOGmXfJNf2yI8MK3qRld9cQovRdUN0Qu3w2mVu3qr9W/0ekkqM8unoOdQwNMlmZxQyAHfCTYX4DJSG/spNzRDguEzzw48CDl99WdvsNi8dnv0ONQOuju7Q1wR9e4vS0+M5zRw3oqvoWEZh58VNV32UKH/FZWvxEAeHtKBb7825YoP6mzuafvI23NSu5sPNjpO3QIPM/0blA7Zi6oHVH7klJxnWL8oy3yWkZ7trFBKqu3H2ukMl8UuLuvw8HPivs/0v9fJ1SODTSXSP0se/DT++P6dVckqTHRbhH7++/JX/ZD5kTW7PXy7IvVd9mlHu4r1oDqzGXioDIDkrD0jAyvYvQpMkFXzz0Pwqz8qqiLG5xW8+yXbJKU55e3CEhsNDrWnPki95jU4oq6/kVXqbtEtnXRLb75vhekBnj1cvKFAZYC35J4m+SGRbEdBosUWUsaXbgBij0yrwJdxy0XvuMroHPhWqm/naTC+LhZNAT3mHqZKPJQwCSMEkEwDT/E5X0r7ZJe4CwPoQFwfEbxIHYEiBoOr4HxCk1gCZG6Cak9KpwJmn6Tom51pSFmTkh9VPwUSNdcy6/YFqJApt21MBUdLIKEjQ/RxmjjTtRQ9oaRUxmgUx+Wx44bxT8BYGb2V2FWqddBL9So3lwPQoXzQJumBfI7lYPUUQzHEmmAB9Br5WkoZNnKsWgkndggzodUk//xAotEHBbPCTe+lNhbsqrhDx2M52KIK9FBeFMVpeFltsyeoxxahjgaXZoNS56HkE0b/97W8vhZ4bOHWOlzSn/re1AwD0Kl141ytAO/4bXhwY7D/RCSHBCDcbMHrXp/4piG5p3dUAz5QmmmR4x25IlMDjTKfwBKhSurFLmlS7382ELM0C2WKA2CyubPp4BljJnzdMjarLJK3fasJPO5wwpZm+rMa99aLBqC3W+POjgQQGyqoIVmKhk1crNChKX7aZyavTyGbymg1XnVvgOi44OmkZGYYfV3/R0ati0tb8lx3tk5iEJHyO2v/L7zzacubSofttmpsPRmBWEK4ozA0IZKEwSOL0MWmxpV0MnMAnc0JnQr34o8AJstBy4DT41M6zYupednocl3QL5+7NLrPQ6X9c+5gCP0mWdf/Mo0n/HvXihE1e5+xoxTe4U+3qMv04/DjJ4CK8A4dkCYytXuUJwKV+9y5pU/02enaY6a5JbYaLDcPMqsvngJkiPsJsMGun11WNZdCSTSjbzEhmszxb4kDWI0wzjM2/EJ8fXxMuxV3gpYw7MSm6un/cof89JwWqH8fKj7SXNHZRAoPiMOWbGcNorWzGsbkPESLc88lXVDw/1CHRpX1LEzGdyhRY7QEtRkNfuJCqGgYbVvMaJdvcmLg8Z/sU1fEMLqqqSD6fK9QEL42GEt0kR1ECHUyXTnkCJdVMLaRAHHJqlNk4KEbluprIMNReDnRbrK7mcNT1g1nfuswN50x3LghmXgGmnS1/okTd6ELw0Z+DSIJTLutoixMaQtaGDrZ4jWzOtRaDq9VMazOCavrByu7eZ+ahqs6p/hiTu6diwqs/ulmGHVuw9itARhsjOCzDqYBBhVyJsR0adtCRigSWB4Gadf/7GYGsm6UrLAp7q5nhFgC26Wc6++FtGQvz+xPaJY/JjhT1Rx3rARssPySXjHIjAJSotwYowqJ/ONV/RiZ60c/y9HgwA0Kop78KXQ2k7AjDPAV0h9DYd8IqZU3ahxksdHA11zY0cH7IsXk02GYfsFUazI15KvuCPlbgUlYRg8ygLzZVupHVAqWSxQphxkhqALjMnIskfQp05o8AMdMOnxNlcNKaaYH2KS6SOKv6sfUqP35OMkI4u4OIQjYIWkryLbmVqBQ1kWJJHicq/K1mb754oE4/747F6NxbdQN4/nmOSdD8j1kixyhDRGOBLdjk8Cg30KKhR4u9NPytd0w0geRmR781D3kd5PRHkgIh0OVTH0MuFo2THjt6gOVizhp5JT7F6bkHqVrDMLiYFrlEXRMxW8KQGHbCUxgoN9pa4JlnMDesZ19OTvgcY6aF4epWf9F9fDyl6HX+LUvzmM/PSp3BdATM+Uv/48LRAKs3PxJY48+GhYcEFVi/Ot6zPAsz5VbskumFYCLILNZLz8hC/bqJNC6DPiaN0dItAFbL31LOA6IJt412+Jl7o9jlPF5HQLxOWkaG4cfVB8TrVTFpa/aAeH3IVqtce4uK1KmbYCdMUzZJSCtILZtpbv6IsOvNlbdE0E21qBoNvLrCfOC7/l6hIovTi3P1VHNsnJi45I2LHvFUGjByqQlXPwIq1bMB5GxYfJMX5yOJYewbePKDhL5NhhP16+pxMeiyHhA85KdkNzUKSKMiDNqft4GDRpn1ACEi//29yM8nKQooEqHz2p8nmYhIg6IIgaAjM0xA8Bg1NMi1hCEEkNu+x0LiZYZBx7wvpx1xCPkCFh8yscd0XUgITb56sezXSdcvRKzZQPSh2AfJ86Nau5A2GSbtL2tP79OoYdIQa/CZe38Vm+ZpQTPlMtccNbOvcLsYmx/L+IDeJlia4jmCg4MuNJYqLTkoD0uwmWiqjFom7c4eThXEGvCt2I8RPwDEzMeUufBFJJx34iN3rUtGVC+lKEHAS9bJsDMosibALN+tYx7YTOjWYQecud06fk8eq6u42Ee352L3FJdo/1dSPUl0cO9Gjf9hJwXDbPgx3EgyVdzlXhcjTIBdMTtEmLUOrJBrlwYaayDJQXkmWPRYIcAT2qzXPV3FZWHtI/0pLHQ1tCSoTbZGcsYZ06PzLpv+yCu0/HV2LaUoQfPrujE0KLL8dfYd+obRfptjBmU3OK3ifBIQnBEHLF/92SWk1SpOMiGceZ0ENcvx5cBlsmHIFStMt8znd3j/lJzqZFSLnsk6IdmAfv2P6wZQr8fyp7FOVHJiBMvt2muBkSMcOLAFYQIq2nSsJxAZH0v0Fea9pK3FOPm9o9dMUT+v6X/ljD7jaqU6F1mdEREF8DUOtB6mROaWNkzJBtbAtD6rWP32D3imH1WssLm+scUKeJz151zb5kSQq7ioqFR/IdNSamDCS8QtSfjC7aSPFHQzaXMB6SIFCK1illoCzKacq5zQNft0JWBr+XfwSwDWhDfyTria+2L+6gntvuRnPuSZ8LN8BBMomaFMLJ3mbTOollq0kEHNNPYMA0iJhkbDHV91xm3f7lxgjQ+38TM5erzJkpqvpxNI1ek02zC3f+ML132sKOhj1CbVE4vBR3eRodbIVz8HOzgAlVKKFvaGxA0gfkFpc2HC150NnzUMvuKeeJcfIurfdUfKTxo4OubEgS+bBJBUqzJpQp1bqGwWBne0UibNcSIuAmqr2HnOh6op95u2cJp9q+kfP+FiQPLQ2QZkVgMV8sz3/vy53BVJk2py4vAfdNvic2q2dPWwEHVaBUiwfl/jCr1HZe3AGb0p8uN0KGEb507D2KLV44NTyKRFujOWApCH/Cc8FgKPoSvmW9U+PiYp/gVFE4Vm6BtkGQ2/rv1+dlDFaHczs9/HxS7lAhvWWmhHBkI0c4TNXnRud5NOEr5QNFMgOPX62KxG6rrzXaZVeVEHJ0+OcfF8/X33FGcHdIe/iKtzgZvYPSvg1RKw0Op+NB9liAjsjVjzSyBMQHqFwUOjh0lDig5YBjTIHz8xMQMmGMvPBobLePflJsOy7L4E3eQGmX0kwjMiSWlWv9iVabaKHbMMd8v3+Vge6Cb0ABmDubkdQf48ozPaXx/jJL2oqnj3RC7b3ySKpbZ9aqggkAMl5xKYgRSrzzgF62V07JPMuPqmxI4a4Xfq4GkMERMcnimYZICjhJdhLBCy5KYKji6j5mj5loAtahiTqjKuY3+IAc0WBrONaVTN2eB3czzlRYVle8QDbHS/e0L7c4oe4vKL/OEjTcTs/ZgC810kIwPDkSsJ845RqnMYvLA6mTTYSphkh1rGGXO4zA8VRgYu7cr2oMLqtDqo4IbSvPGBBXUY36/Bcv2w4gMC0YVhFk/Wfe8FbJRehpvAxzlX5rd5mn7KK4z39sql7qiBKbm67w+/8O9VDcaHPOLrac/F2rpwurGuzOIWl2+fOQARCg1e4Y063+o0mABmastbtTkHvuofLrLym+IolSLhe7X7eZJRbBTGfJ1lScy1IGwNIs6aQ/YqP5KZ0nAAo6pMPXbRTfNpZPvfNzRiSU1t1dzEMIIT4bpmAg6YjdgSSZ7GJas8wRPjp5NtvsucND9YDkdUlamHI7pp5tKG/n1Dw5HU1FbNTQyj+t9iciWuF4UMU8OP01wF2iPJ03AEm2cZ+Olkm9HZllw03qGvCfr2FqWnx3Oa1ZFXTPd6kvqT7/lkcgCX3wDRhoYwsx6xantOHDIFOleHlkra57Mhyq/3AmSMBYKJqbwMZDkNa7OOZeZg3s6otaKhagVOWI5wWp/DlT2GpnWzusZ1quf6o8I1UNG5F+Z79CYpyup1XMWf41K8x6lr3aOqf4RDctM2P1Od2f5eX1Id43/8uv+c476OP6dDFWHA4RjH36/iCh1I2AiRPV0KNkITaJrC/6oPEoFm+hKoib5Qw/5dvovT5J9o3/U40BBAAzUJkOkaj7PDmTwRE9vsi8Cm+lIT9dB9VZCz2DI/FzuwNZBMqqRAqZHiFhXHpCwxxrtDbkECkQRqXaTStMy+3RFaZYuhFlkKnZ55mkK6kZ9BfUiJAdfuwgLk3RXKWujKDW3VL0Ok5uopVBbriQybVbSnbkjbQv+UT2igL4H494U6BWq/NXAg7EtA8btC3QDYxjl9j6qnHPp0eAJwOORodG1WeHjGw9hXPJ1C3w1XDrbIkmgaHE6YhLaGIqiZoVT3FXULKfET6krA76cr1LAfMvIK/IciqIGhVAcz+YSrnm2Np9rbZFedC6i/+xLQRF2hWQ8oWuEIFP0RtUTR+5jg2rh/6kjTSYGO8AAHUql6jSHUiYDS5Csqnh+SI6Q9Www2ylCYWZuOISwzOE2jsDlNZtt4Hw7wTZJW8ESmrWIkmlDLTFLFxyVQqGDZURnjsq34Ps7OjzGBtMI4LJVKDprSWBaNEPrWWQozze9PaJc8JjuyBaKifcpsIKNXWQOuY2wXuPqH9u2RODkqycG5UlnDSTpjuWwkMu3Thxjar9GFit4i5WbtfIqLJM6GWKNX+fFzksWSfjGppJBLWU8j75/nmPzyMUugaYcthmRgKdysY24SzdTb/N/+O+IrygUyk8Qal7yebeBeU7O05BYYaWvoFgb9yzdxUdAXgQuCvlR3XpOg4rZIwLU8VQae1QzFmkYGpxWhjaEIaqIu1XK//o6n8yxOL87VU32i1gxN0vMENTkkhbqGRjoSYEuygaHKoHZJcRkZbWIIrexUjy5UNGR2wkeIZY0o+bcUJvx/L/LzSdZIW6hoqaXQtNTGbxYaaX+H+LdFhlsKNmOudE/Bkqk2FSylRgo4b68gBUwGSQFTGkqhaFndmlk3SoYXqkzanUb7FiprLdxIUyZtpCnWNAJmpxSaA6mghkFCgzMlyRZ4KJKdIxltdtnEd9JW5J3GUmhNymTFAozJlMNmZEi06vFJKAAVeRJYTZ5KdwwkJkYQz4NEGvBgSCSzbVy2gpIRGolhtmqShjEHel9CCeNAQmwpjoEcZgLoj7fpoMfiETddCh5z0wTmTTUxxFXNNRSaJhsi7S0WpJlUIxNNgCiv8DKEpVGsRlhC7YaEDREJbEFYAtXKkSPV9eEQj1DsvaEM7LehWDc+Mu9KxbGRKQbHRYZCC8tUuhGgymAopoZL/I+FvBGqDGqEKtato1CG8GZLNbiLJOC6SqDSbRExD0T2r5/Bq1KuHNwqsiTaO6YcvAVof4fvlHKDe4YhgJo4LfVF8IViV2oien/qAWvQF0sVMT02kUY9EhqWUoI3ZzJii1PiB3Q8pfBQApPpTo0HSsPbMIUEIonqdsy45e6YUt6wQKE67TRt9g7VZHv5NSZPAK8tWBqdkYu8LDHzVN6qSAIaWaDSGblZ+0jvvLly0MAsifaEFgyMAhzVgnTwmS1Iai6Iunlto/ojNSYIkniExhSDR2YMhfaLPZ7i5ACNW0MR/IV2pbqRqVkBqQYlngIcj3gig3PPd6iqUKEZnmWEsjNRiFZrgrjE4+hfKDk8QX3KlcPqMyRmDb5OMLhLWG2RRNEsRaVpmYtJIzTLlUNtciS6Wf852ykmfboUnPNpAu1hNx/bAjjg5kngQ22eyqhluVW5cnmbplblXfo0HntqchOfwagmNb/7ZRyn5K5eEjq9L9YdKvESnfhsG7iatdrKPdoECpXnXEuE9A13R9MKPwmRRHXGHV2cTmmC9g95S59YSCFfjggUZjK05HoJOhclg3tuw+vuaKAzBmXvYmnm3Wru5cpEyje/1xViWIg2EUhkzqoslcHU278IBefbvlQ2yfYEBh6K8qaYUpmfomlT8pdiMqwBpArIAdQ2EunEMGhbaJB6BqF2Xo8G13eqjsKNfajAv9qgcoFxfvhYBLmPPVtT4V/fcDHxl3/Bqm9qGvqtgd4uMHUwo0BvKgaLKJ9J2JtDmOPpcayM7luzi5YxqyhXVfaygWiqe62g5ASN7SBX5QsF76Z8iIsDqhxM2VaUG0CqsErBZZoQT2PK75ElCPEJ0i9RGpWhlyZuqjXPSaKGI6wcTTJSSKEG+xSmryd55GKvIrs8j7r1OWoX9YlyPDGvLFcSfvBBFFU/41Bw4TYuADPZc5QgBpSPIuaVFSMJoKxEvaWYjH4sE/V8AfOAhAFMAT0AakygfNdjr3q7B1UpzZP4V5fbT5N6sudf7ipyppMryhJ676UJVe83lv1Rg2LwlBPrVw3gikGpuOQshWEQ1BDyQVBO7KUfl2CGyyStoyP3nBVG4EjDmcAIQyOU7oKGDKzlWgu0IT8B7sUvw0D2jNfeDN1TTeXSWCQKsTzmn5uSmtKnpA7LZOYlY9S/aARWyzClYgnMPp9s1r/wC0y2Hvj6sqnOFXlXvzuM1asPRwAR1YDkX4z6/SNARb8LNP57nD+rbz5r2WNgezVVR/mKWd6kmlwp/p01UUr2hhqsCZpFLAxrHvncb1LNU58vzDzdJYwVdvhKIZEDjT1CWUjD2KCGr+R/SJ3JLMDTe3D9qK4QEidAjAGGiSpogPNkG7HRAaRTLUunUAaIVtBooYhC4Iord7WlL/8jOlyB1BpG1bUqikEWaGXlcRPUvCQxE2DWurgHHgzcmkS/mpNWCbasc+0AL2axMsgGTdEvZYfVgdQSIm2ItYwkqAdtCI8rGV41PR4E0mBomMgETLgRxa4HpPO/84ECmZDKygAlzj3PBVuhm5BCQF7Hs1oQKqSMwPIgZtJ/JCB5sA9lHpNIAtPojaOpGMxM6mAzNDfDCDIOd2WKYDmSSD/gTZoDG8VNjN4uZgYx4MoGHlLwlgQQ8o1WdeO2EFZym9hUC/0CRM9RpYuTnDrcMavgH8uctFKlQYyhcFKSU2uVkmgDqLEMkygCVpkeFhizmOAcwSDYF21Rm3BdQUysn8RNagf7RNdmTjYCmpNNGRZyA0HB2ogpVEHY1mpiB5hOj00Ta4U3kXI5aVxXq7xSa7N14yLNSKK6RNJmjU2q5jOJUUz4MpFxVMzhaDfuCyHDgXLy0TDsPUB0Hx9PKRoiIsoV5ygVSxcuLmOzbJHEXJxQ5T4kY8Q6rosqSyj1HkHuTvhCqElSXR5Fcoz6irlLJPI/W4VXtYubqXSZEonkIru7TPHRPUnN4Ud/noGmT3fUFfQQH+Eup/tIPL8nkWhq4D86+ROcuUykCt6q9Lc0qxgCTSYBbQk3q8C09qbrw9Mq7QRQhTCKEEeXVKV+9aMuiYGr15cjC6YwE9F30BiO1OuockQH1ZXoS9NoRGZC9w4igyF5xdpiRb8927JUdmtDM1rQeXqTfIk0W9UXS9F5FH3i75bE1zV4NgDSyQV3fTPARJUmteCg0a6KqsYmjiLEsBROPSjIdTS418n9+OAKit3baD8+KKQ2w0UZItuTaVq7G9qloR7dr4swRx+2W24DnsSv4kLI8aGep03PIL9iKysS+d/Khle1C/Qe3eL92VNcov1fSfVEtSAqrqviTR2mLh/KnlSVhql3NwTz3Q785WaAK3hSBKwp/eKNcgR4Ms1Hut+N7cPW8jsuzGWePsWAZkCkSAIMiHR6hKEemPnAXkUgmYFyKaSkD7EwUiRvIExMsjH4MYv2u9BX8ouOeUzT5YmQfxMchV+l+Uwa912YCE+vO+g0GNHAV64lS+hJcLCmML8qU3a4boS6kBvaLR9PuKY9H5N8RDPggZRhhjogqUr7JatypYw44DbobCmt//4OHReAz/2iebKkItfuCLw8UZJlvWm/fk0mGw8GUn0ZcuIQH8fsplBsGKW0/veNU5sBzhUUAZmMgJHDtK4CL7LkSw1wdPmU1LxEjxHDzEgu8w2bYyi6yZIqiVPFWlJVwfc6Es6k1E49muxI443RrZXFpvR2kdYNpK6SE7wIN0tv5RDlakjqFAkJnkTLqcgVUzmcgKqZ0tVZpWR8ZDw8m0Q1dYF0IWatadTWqRtcTV49P2oJ6cD0F8gwdbB7ZCj/xHARp0wk4eJ4R6cdi94U+VFlDxV5CIPAGdbahY0yYdpoUzzkFoagiNduhj49XKTYv4lE/jduQoq7pqY0e53LyJ4CUY7hsR2k1Pe1uxOWkA6vHeNlSehc4pXmJFpXcoyL5+vvu6c4O6A7bNohhRqwLdFWUhmFzenWGgTO18buUOg0c822BMwiN9II5A9j7VnqdaktyRunnAy1dUIMfZq8eYSRaRI8f2ZS7Nt1Vfxv3+c1EZggLXqTwAOpglrhu+Dswq9MCHffPIAwye82yiwRm2FNaRSWVq4YlPWN6KPK5iYzjcwgwdDBtGEKErqSV7UWghgmj1nEps4VbaSgVswnQELfZlpRJOplOID52ggLdRo2F2dwG3MoqEOaA0y01nyHyvxpruYYcsBFPWuZMQBa74oAPMR8dxQbRQ47tzQWdKKpqD4wusqzsiripJ5V8O60X5x0oZgf8khMUAXs73zx1q+JHOI2s8sGSeKuZv2gS8blwex04g4DS1LkaqWscoTMahIqBZkpUJisZaLVRnIMjzogadt995hMliJtnGGHZ2pqc/V0auGNn8HNoDaVZ86095nUdMCuZBzH8HgCMvM1GxdFyr1xhh0ixavN1dOphTeORD+D2u0uUkgZaDyrSeorHmj7b2uCmVSqprgj16df9NhNTIGV0dmahqrL9V2P+ZzgpjWtG9eJkWvefaONrI87wxH6P/3yr/qrFw2T2vC4l1HRl7160SRFbX/Af1Z5ER/Q+3yP0pL8+urF3RnXPqLmr9eoTA4Di1eYZ4ZInuiBaUdzkz3WAd9JOk1Ooo6kK+7ztlfxPq7ii6JK6riWuHiHvyWS7pd4mdTnQZ/R/ib7cK5O5wqrjI6fU+bQ+dULdfuvXggyv2oC7ZU+VMBiJlgF9CG7PCfpvpf7TZyW3HZTxuIKW/93hH9v+hJ/mhU6PPec/sgzQ0at+fAmFWV7/Mk9oOMpxczKD9l9/BW5yPaxRO/QId4939ZpvIjTjIyJviNYs796ncSHIj6WLY+hPv4TY3h//P5f/w+t09y6EK8IAA== + + + dbo + + \ No newline at end of file diff --git a/src/Libraries/SmartStore.Data/SmartStore.Data.csproj b/src/Libraries/SmartStore.Data/SmartStore.Data.csproj index aee5f01421..8272d36d87 100644 --- a/src/Libraries/SmartStore.Data/SmartStore.Data.csproj +++ b/src/Libraries/SmartStore.Data/SmartStore.Data.csproj @@ -372,9 +372,9 @@ 201511271019577_ExportFramework3.cs - - - 201512091408315_ImportFramework.cs + + + 201512101150534_ImportFramework.cs @@ -699,8 +699,8 @@ 201511271019577_ExportFramework3.cs - - 201512091408315_ImportFramework.cs + + 201512101150534_ImportFramework.cs diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/IImportProfileService.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/IImportProfileService.cs index 85d6f64dec..366cb9d5bb 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Import/IImportProfileService.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/IImportProfileService.cs @@ -1,5 +1,6 @@ using System.Linq; using SmartStore.Core.Domain; +using SmartStore.Core.Domain.DataExchange; namespace SmartStore.Services.DataExchange.Import { @@ -11,7 +12,7 @@ public interface IImportProfileService /// Profile name /// /// Inserted import profile - ImportProfile InsertImportProfile(string name, string entityType); + ImportProfile InsertImportProfile(string name, ImportEntityType entityType); /// /// Updates an import profile diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportProfileService.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportProfileService.cs index 76f7a0b083..21bbb22823 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportProfileService.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportProfileService.cs @@ -29,10 +29,9 @@ public ImportProfileService( _dataExchangeSettings = dataExchangeSettings; } - public virtual ImportProfile InsertImportProfile(string name, string entityType) + public virtual ImportProfile InsertImportProfile(string name, ImportEntityType entityType) { Guard.ArgumentNotEmpty(() => name); - Guard.ArgumentNotEmpty(() => entityType); var task = new ScheduleTask { diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs index 2c5040e624..4cf43afe3f 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs @@ -6,12 +6,16 @@ using SmartStore.Admin.Extensions; using SmartStore.Admin.Models.DataExchange; using SmartStore.Core.Domain; +using SmartStore.Core.Domain.DataExchange; using SmartStore.Core.IO; using SmartStore.Services; using SmartStore.Services.DataExchange.Import; using SmartStore.Services.Helpers; +using SmartStore.Services.Localization; using SmartStore.Services.Security; using SmartStore.Services.Tasks; +using SmartStore.Utilities; +using SmartStore.Web.Framework; using SmartStore.Web.Framework.Controllers; using SmartStore.Web.Framework.Filters; using SmartStore.Web.Framework.Security; @@ -42,20 +46,32 @@ public ImportController( private void PrepareProfileModel(ImportProfileModel model, ImportProfile profile, bool forEdit) { - model.Id = profile.Id; - model.Name = profile.Name; - model.FolderName = profile.FolderName; - model.FileNames = profile.GetImportFiles(); - model.EntityType = profile.EntityType; - model.Enabled = profile.Enabled; - model.Skip = profile.Skip; - model.Take = profile.Take; - model.Cleanup = profile.Cleanup; - model.ScheduleTaskId = profile.SchedulingTaskId; - model.ScheduleTaskName = profile.ScheduleTask.Name.NaIfEmpty(); - model.IsTaskRunning = profile.ScheduleTask.IsRunning; - model.IsTaskEnabled = profile.ScheduleTask.Enabled; - model.LogFileExists = System.IO.File.Exists(profile.GetImportLogPath()); + if (profile != null) + { + model.Id = profile.Id; + model.Name = profile.Name; + model.FolderName = profile.FolderName; + model.EntityType = profile.EntityType; + model.Enabled = profile.Enabled; + model.Skip = profile.Skip; + model.Take = profile.Take; + model.Cleanup = profile.Cleanup; + model.ScheduleTaskId = profile.SchedulingTaskId; + model.ScheduleTaskName = profile.ScheduleTask.Name.NaIfEmpty(); + model.IsTaskRunning = profile.ScheduleTask.IsRunning; + model.IsTaskEnabled = profile.ScheduleTask.Enabled; + model.LogFileExists = System.IO.File.Exists(profile.GetImportLogPath()); + model.EntityTypeName = profile.EntityType.GetLocalizedEnum(_services.Localization, _services.WorkContext); + + model.ExistingFileNames = profile.GetImportFiles() + .Select(x => Path.GetFileName(x)) + .ToList(); + } + + if (forEdit) + { + model.AvailableEntityTypes = ImportEntityType.Product.ToSelectList(false).ToList(); + } } #endregion @@ -87,6 +103,46 @@ public ActionResult List() return View(model); } + public ActionResult Create() + { + if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageImports)) + return AccessDeniedView(); + + var model = new ImportProfileModel(); + PrepareProfileModel(model, null, true); + + return View(model); + } + + [HttpPost, ParameterBasedOnFormName("save-continue", "continueEditing"), FormValueRequired("save", "save-continue")] + public ActionResult Create(ImportProfileModel model, ImportEntityType entityType) + { + if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageImports)) + return AccessDeniedView(); + + if (!System.IO.File.Exists(model.TempImportFile)) + { + ModelState.AddModelError("ImportFiles", T("Admin.DataExchange.Import.MissingImportFile")); + } + else if (ModelState.IsValid) + { + var profile = _importService.InsertImportProfile(model.Name, model.EntityType); + + if (profile != null && profile.Id != 0) + { + var folder = profile.GetImportFolder(true, true); + var destPath = Path.Combine(folder, Path.GetFileName(model.TempImportFile)); + + FileSystemHelper.Copy(model.TempImportFile, destPath, true, true); + + return RedirectToAction("Edit", new { id = profile.Id }); + } + } + + PrepareProfileModel(model, null, true); + return View(model); + } + public ActionResult Edit(int id) { if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageImports)) @@ -158,6 +214,44 @@ public ActionResult DeleteConfirmed(int id) return RedirectToAction("Edit", new { id = profile.Id }); } + [HttpPost] + public JsonResult FileUpload(int id) + { + var success = false; + string error = null; + string tempFile = null; + + if (_services.Permissions.Authorize(StandardPermissionProvider.ManageImports)) + { + var postedFile = Request.ToPostedFileResult(); + if (postedFile != null) + { + if (id == 0) + { + tempFile = Path.Combine(FileSystemHelper.TempDir(), postedFile.FileName); + FileSystemHelper.Delete(tempFile); + } + else + { + } + + success = postedFile.Stream.ToFile(tempFile); + + if (!success) + error = T("Admin.Common.UploadFileFailed"); + } + } + else + { + error = T("Admin.AccessDenied.Description"); + } + + if (error.HasValue()) + NotifyError(error, true); + + return Json(new { success = success, tempFile = tempFile }); + } + [HttpPost] public ActionResult Execute(int id) { diff --git a/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ImportProfileModel.cs b/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ImportProfileModel.cs index a1a663f693..77bb5f64ea 100644 --- a/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ImportProfileModel.cs +++ b/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ImportProfileModel.cs @@ -1,7 +1,9 @@ using System.Collections.Generic; +using System.Web.Mvc; using FluentValidation.Attributes; using SmartStore.Admin.Models.Tasks; using SmartStore.Admin.Validators.DataExchange; +using SmartStore.Core.Domain.DataExchange; using SmartStore.Web.Framework; using SmartStore.Web.Framework.Modelling; @@ -10,17 +12,18 @@ namespace SmartStore.Admin.Models.DataExchange [Validator(typeof(ImportProfileValidator))] public partial class ImportProfileModel : EntityModelBase { + [SmartResourceDisplayName("Admin.Common.ImportFiles")] + public List ExistingFileNames { get; set; } + [SmartResourceDisplayName("Admin.DataExchange.Import.Name")] public string Name { get; set; } [SmartResourceDisplayName("Admin.DataExchange.Import.FolderName")] public string FolderName { get; set; } - [SmartResourceDisplayName("Common.Files")] - public List FileNames { get; set; } - [SmartResourceDisplayName("Admin.Common.Entity")] - public string EntityType { get; set; } + public ImportEntityType EntityType { get; set; } + public List AvailableEntityTypes { get; set; } [SmartResourceDisplayName("Common.Enabled")] public bool Enabled { get; set; } @@ -42,5 +45,7 @@ public partial class ImportProfileModel : EntityModelBase public ScheduleTaskModel TaskModel { get; set; } public bool LogFileExists { get; set; } + public string TempImportFile { get; set; } + public string EntityTypeName { get; set; } } } \ No newline at end of file diff --git a/src/Presentation/SmartStore.Web/Administration/SmartStore.Admin.csproj b/src/Presentation/SmartStore.Web/Administration/SmartStore.Admin.csproj index 7bc7cfc138..1cb806ab59 100644 --- a/src/Presentation/SmartStore.Web/Administration/SmartStore.Admin.csproj +++ b/src/Presentation/SmartStore.Web/Administration/SmartStore.Admin.csproj @@ -537,6 +537,8 @@ + + diff --git a/src/Presentation/SmartStore.Web/Administration/Validators/DataExchange/ImportProfileValidator.cs b/src/Presentation/SmartStore.Web/Administration/Validators/DataExchange/ImportProfileValidator.cs index 3760f5bae1..044d217456 100644 --- a/src/Presentation/SmartStore.Web/Administration/Validators/DataExchange/ImportProfileValidator.cs +++ b/src/Presentation/SmartStore.Web/Administration/Validators/DataExchange/ImportProfileValidator.cs @@ -1,6 +1,4 @@ -using System.IO; -using System.Linq; -using FluentValidation; +using FluentValidation; using SmartStore.Admin.Models.DataExchange; using SmartStore.Services.Localization; @@ -13,10 +11,6 @@ public ImportProfileValidator(ILocalizationService localization) RuleFor(x => x.Name) .NotEmpty() .WithMessage(localization.GetResource("Admin.Validation.Name")); - - RuleFor(x => x.FolderName) - .Must(x => x.HasValue() && !x.IsCaseInsensitiveEqual("con") && !Path.GetInvalidFileNameChars().Any(y => x.Contains(y))) - .WithMessage(localization.GetResource("Admin.DataExchange.Import.FolderName.Validate")); } } } \ No newline at end of file diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Import/Create.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Import/Create.cshtml new file mode 100644 index 0000000000..57aaf80b7a --- /dev/null +++ b/src/Presentation/SmartStore.Web/Administration/Views/Import/Create.cshtml @@ -0,0 +1,24 @@ +@using SmartStore.Admin.Models.DataExchange; +@model ImportProfileModel +@{ + var title = string.Concat(T("Admin.Common.AddNew"), " ", T("Common.Profile")); + ViewBag.Title = title; +} + +@using (Html.BeginForm()) +{ +
+
+
+ + @title - @Model.Name @Html.ActionLink("(" + T("Admin.Common.BackToList") + ")", "List") +
+
+ +
+
+ @Html.Partial("_CreateOrUpdate", Model) +
+} \ No newline at end of file diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Import/List.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Import/List.cshtml index 105b8b85b4..11ae7b52b0 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Import/List.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Import/List.cshtml @@ -12,7 +12,7 @@ @T("Common.Import")
@@ -28,7 +28,7 @@
@T("Admin.DataExchange.Import.Name") @T("Common.Enabled") @T("Admin.Common.Entity")@T("Common.Files")@T("Admin.Common.ImportFiles") @T("Admin.System.ScheduleTasks.LastStart") @T("Admin.System.ScheduleTasks.NextRun") @T("Admin.Common.Actions") - @profile.EntityType.NaIfEmpty() + @profile.EntityTypeName - @(string.Join("
", profile.FileNames)) + @(string.Join("
", profile.ExistingFileNames))
diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Import/_CreateOrUpdate.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Import/_CreateOrUpdate.cshtml new file mode 100644 index 0000000000..15820d8042 --- /dev/null +++ b/src/Presentation/SmartStore.Web/Administration/Views/Import/_CreateOrUpdate.cshtml @@ -0,0 +1,124 @@ +@using SmartStore.Admin.Models.DataExchange; +@model ImportProfileModel +@{ + Html.AddScriptParts("~/bundles/fileupload"); + Html.AddCssFileParts("~/css/fileupload"); +} + +@Html.ValidationSummary(false) +@Html.HiddenFor(model => model.Id) +@Html.HiddenFor(model => model.TempImportFile) + + + + + + + + + + + + + + + @if (Model.Id != 0) + { + + + + + + + + + + + + + + + + + + + + + } +
+   + + +
+ + + @T("Admin.DataExchange.Import.FileUpload") + + + + + +
+
+
+
+
 
+
+
+ +
+ @Html.SmartLabelFor(x => x.Name) + + @Html.EditorFor(x => x.Name) + @Html.ValidationMessageFor(x => x.Name) +
+ @Html.SmartLabelFor(x => x.EntityType) + + @Html.DropDownListFor(x => x.EntityType, Model.AvailableEntityTypes) + @Html.ValidationMessageFor(x => x.EntityType) +
+ @Html.SmartLabelFor(x => x.FolderName) + + @Html.EditorFor(x => x.FolderName) + @Html.ValidationMessageFor(x => x.FolderName) +
+ @Html.SmartLabelFor(x => x.Enabled) + + @Html.EditorFor(x => x.Enabled) + @Html.ValidationMessageFor(x => x.Enabled) +
+ @Html.SmartLabelFor(x => x.Skip) + + @Html.EditorFor(x => x.Skip) + @Html.ValidationMessageFor(x => x.Skip) +
+ @Html.SmartLabelFor(x => x.Take) + + @Html.EditorFor(x => x.Take) + @Html.ValidationMessageFor(x => x.Take) +
+ @Html.SmartLabelFor(x => x.Cleanup) + + @Html.EditorFor(x => x.Cleanup) + @Html.ValidationMessageFor(x => x.Cleanup) +
+ + \ No newline at end of file diff --git a/src/Presentation/SmartStore.Web/App_Data/ImportProfiles/produkte-importieren/Content/1-165-0001-produktcsvexport.csv b/src/Presentation/SmartStore.Web/App_Data/ImportProfiles/produkte-importieren/Content/1-165-0001-produktcsvexport.csv new file mode 100644 index 0000000000..4750e5d752 --- /dev/null +++ b/src/Presentation/SmartStore.Web/App_Data/ImportProfiles/produkte-importieren/Content/1-165-0001-produktcsvexport.csv @@ -0,0 +1,219 @@ +ProductTypeId;ParentGroupedProductId;VisibleIndividually;Name;ShortDescription;FullDescription;ProductTemplateId;ShowOnHomePage;HomePageDisplayOrder;MetaKeywords;MetaDescription;MetaTitle;SeName;AllowCustomerReviews;Published;SKU;ManufacturerPartNumber;Gtin;IsGiftCard;GiftCardTypeId;RequireOtherProducts;RequiredProductIds;AutomaticallyAddRequiredProducts;IsDownload;DownloadId;UnlimitedDownloads;MaxNumberOfDownloads;DownloadActivationTypeId;HasSampleDownload;SampleDownloadId;HasUserAgreement;UserAgreementText;IsRecurring;RecurringCycleLength;RecurringCyclePeriodId;RecurringTotalCycles;IsShipEnabled;IsFreeShipping;AdditionalShippingCharge;IsEsd;IsTaxExempt;TaxCategoryId;ManageInventoryMethodId;StockQuantity;DisplayStockAvailability;DisplayStockQuantity;MinStockQuantity;LowStockActivityId;NotifyAdminForQuantityBelow;BackorderModeId;AllowBackInStockSubscriptions;OrderMinimumQuantity;OrderMaximumQuantity;AllowedQuantities;DisableBuyButton;DisableWishlistButton;AvailableForPreOrder;CallForPrice;Price;OldPrice;ProductCost;SpecialPrice;SpecialPriceStartDateTimeUtc;SpecialPriceEndDateTimeUtc;CustomerEntersPrice;MinimumCustomerEnteredPrice;MaximumCustomerEnteredPrice;Weight;Length;Width;Height;CreatedOnUtc;CategoryIds;ManufacturerIds;Picture1;Picture2;Picture3;DeliveryTimeId;QuantityUnitId;BasePriceEnabled;BasePriceMeasureUnit;BasePriceAmount;BasePriceBaseAmount;BundleTitleText;BundlePerItemShipping;BundlePerItemPricing;BundlePerItemShoppingCart;BundleItemSkus;AvailableStartDateTimeUtc;AvailableEndDateTimeUtc;StoreIds;LimitedToStores;Name[DE];ShortDescription[DE];FullDescription[DE];Name[en];ShortDescription[en];FullDescription[en] +5;0;True;_Zero Price;;"

Optisch zum Verwechseln ähnlich, ebenso kompakt und leicht wie die erfolgreiche SD19, aber mit noch besserer Auflösung, präsentiert sich die brandneue AEE SD21 PRO Action-Cam. Die SD21 PRO ist eine komplette Neuentwicklung, mit Innovationen und einer Ausstattung, die es bisher in diesem Preissegment noch nicht gab.
Bei der SD21 PRO ist die Monitor-Rückwand wie auch die Fernbedienung ebenso selbstverständlich wie der aufsteckbare Zusatzakku für noch längere Power.
Für einfaches, unkompliziertes Justieren der Kamera ist ein Laserpointer integriert. Der 10-fach Digitalzoom und die hochwertige Optik garantieren für optimale Aufnahmeergebnisse bei allen Bedingungen.

Highlights SD21 PRO:

  • 1/3 Zoll CMOS-Sensor 8,0 Megapixel
  • 170° Weitwinkel-Objektiv, Blende F/3.0
  • 10x Digitalzoom
  • Automatische Belichtung und Weissabgleich
  • Externes TFT-Display mit Echtzeit-Anzeige für Video und das Abspielen aufgezeichneter Inhalte
  • Laserpointer als Aufnahmeorientierung
  • Selbst-/Zeit-Auslöser mit Kontroll-LED
  • Eingebautes Mikrofon für hochwertige Stereo-Voice-Aufnahmen
  • Wasserdichtes Gehäuse bis 60 Meter (IP68-Standard)
  • Hochleistungs-Lithium-Batterie
  • Aufsteckbarer Zusatzakku mit eigener Ladestandsanzeige - verdoppelt die Aufnahmedauer
  • Auto Stand-by zur Energieeinsparung
  • Funktionen: HD-Videoaufnahme / Foto
  • Recording MOV Videos können direkt am PC wiedergegeben oder auf Video-Websites hochgeladen werden
  • Photo 180-Grad-Umkehr-Funktion
  • Externe Micro SD/MMC-Speicherkarte, unterstützt bis max. 64GB (nicht enthalten)
  • Speicherkapazität Alarm
  • Schneller Vor- und Rücklauf, Funktion zum Überspringen von Inhalten in das nächste Segment
  • Unterstützung USB2.0
  • HDMI-Ausgang, AV-OUT-Funktion
  • Support-System: Windows 98SE/2000/Me/XP/Vista/Win 7/Mac OS

Grösse: ca. 61x43x40mm (BxHxT)

Gewicht: 88g ohne Bildschirm, 112g mit Bildschirm

Technische Daten SD21 PRO:

  • Auflösung/Sensor: 8.0M CMOS-Sensor (3200 * 2400)
  • Optik / Linse: 170° Weitwinkel-Objektiv, Blende F/3.0
  • Gehäuse: IP68 wasserdichtes Gehäuse bis 60m
  • Memory-Karte: Micro SD unterstützt bis 64GB (nicht enthalten)
  • Photo-Modus: 3M (2048 * 1536) / 5M (2560 * 1920) / 8M (3200 * 2400)
  • Video-Aufnahmemodus: 1080P 720P WVGA QVGA
  • Bildrate: 1080P/30fps 720P/30fps WVGA/60fps QVGA/30fps
  • Video-Aufnahmeformat: MOV (H.264-Video-Kompression)
  • Photo-Format: JPEG
  • Aufnahmekapazität (2GB SDKarte):
  • Photos 3M (1900pcs), 5M (1160pcs), 8M (770pcs) /
  • Videos: 720P/60min, WVGA/135min
  • Laserpointer/Laserleistung: 1MW
  • AV OUT: Unterstützung NTSC / PAL VGA und HDMI
  • USB: USB2.0
  • Mikrofon: 2 Mikrofone, eingebaute
  • Leistungsaufnahme: 500mA@3.7V (MAX)
  • Lithium-Batterie: 1000mAh
  • Batterielaufzeit: 2.5h / Batterie
  • Betriebssystem: Windows XP SP2/Vista oder höher / Mac OS. CPU:
  • Pentium4 1.5GHZ oder höher RAM: min. 1GB
  • RTC-Funktion: Unterstützung
  • Lagertemperatur: -20 bis -60 
  • Betriebstemperatur: -10 bis -50 
  • Luftfeuchtigkeit bei Betrieb: 15 85% RH

 

";2;True;0;;;_Wasser;_zero-price-3;True;True;;;;False;0;False;;False;False;0;False;0;1;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;0;False;False;0;0;1;0;False;1;10000;;False;True;False;False;0.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;42302,5461930208;"1;2095";;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000696-_zero-price.jpg;;;2;;True;l;35.0000;100;;False;False;False;;;;1;True;;;;;; +5;0;True;Bundle Item 2;;;2;False;0;;;;bundle-item-2;True;True;;;;False;0;False;;False;False;0;True;10;1;False;;False;;False;100;0;10;True;False;0,0000;False;False;1;0;10000;False;False;0;0;0;0;False;1;10000;;False;False;False;False;19.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;41965,4767811343;;;;;;;;False;ounce;;;;False;False;False;;;;;False;;;;;; +5;0;True;Bundle Item 1;;;2;False;0;;;;bundle-item-1;True;True;;;;False;0;False;;False;False;0;True;10;1;False;;False;;False;100;0;10;True;False;0,0000;False;False;1;0;0;False;False;0;0;0;0;False;1;10000;;False;False;False;False;84.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;41965,4671613079;;;;;;;;False;ounce;;;;False;False;False;;;;;False;;;;;; +5;0;True;_Download;;"

Downloadable product.

";2;False;0;;;;_download;True;True;;;;False;0;False;;False;True;8;True;10;1;False;;False;;False;100;0;10;False;False;0,0000;False;False;1;0;10000;False;False;0;0;1;0;False;1;10000;;False;False;False;False;3.8000;0.0000;0.0000;;0.0;0.0;False;0.0000;1000.0000;0.0000;0.0000;0.0000;0.0000;41863,7438013542;"1;2095";;;;;;;False;ounce;;;;False;False;False;;;;;False;;;;;; +5;0;True;_Attribut Test;;"

Continually incubate standards compliant content vis-a-vis multifunctional portals. Dynamically exploit collaborative strategic theme areas vis-a-vis extensive partnerships. Monotonectally maximize user friendly relationships for backward-compatible alignments. Objectively deliver covalent opportunities after exceptional scenarios. Objectively drive backend paradigms via excellent meta-services. Uniquely customize sticky core competencies rather than leveraged internal or "organic" sources. Objectively conceptualize client-based users without customer directed applications. Continually generate backend processes and market-driven markets. Proactively evisculate visionary testing procedures with fully tested networks. Collaboratively facilitate B2C schemas vis-a-vis covalent meta-services. Proactively recaptiualize progressive quality vectors vis-a-vis frictionless supply chains. Distinctively synthesize revolutionary leadership vis-a-vis strategic e-markets. Distinctively pontificate principle-centered benefits with pandemic resources. Professionally pontificate multifunctional strategic theme areas via low-risk high-yield data. Uniquely underwhelm technically sound information before functional synergy. Progressively utilize 24/365 ROI whereas client-based interfaces. Seamlessly reintermediate alternative customer service through plug-and-play quality vectors. Professionally repurpose one-to-one scenarios without visionary supply chains. Enthusiastically unleash timely applications after an expanded array of e-commerce. Monotonectally pursue virtual intellectual capital after high standards in scenarios. Professionally benchmark end-to-end internal or "organic" sources with maintainable supply chains. Authoritatively disseminate high-payoff imperatives for stand-alone infomediaries. Completely network stand-alone initiatives for market positioning intellectual capital. Appropriately deliver process-centric collaboration and idea-sharing after multifunctional leadership. Energistically unleash open-source vortals vis-a-vis transparent niches.

";2;False;0;;;;ab-22;True;True;SKU-Tester;;;False;0;False;;False;False;7;True;10;1;False;;False;;False;100;0;10;True;False;0,0000;False;False;1;2;10000;True;False;0;1;1;0;False;1;10000;;False;False;False;False;0.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;1000.0000;0.0000;0.0000;0.0000;0.0000;41833,6856570949;"1;2095";;;;;2;;False;ounce;;;;False;False;False;;;;;False;;;;;; +5;0;True;_GiftCard;;

GiftCart for testing.

;2;False;0;;;;_giftcard-2;True;True;;;;True;0;False;;False;False;0;True;10;1;False;;False;;False;100;0;10;False;False;0,0000;False;False;1;0;10000;False;False;0;0;1;0;False;1;10000;;False;False;False;False;10.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;1000.0000;0.0000;0.0000;0.0000;0.0000;41701,4763476505;1;;;;;;;False;ounce;;;;False;False;False;;;;;False;;;;;; +5;0;True;GiftCard;;;2;False;0;;;;_giftcard;True;True;;;;True;0;False;;False;False;0;True;10;1;False;;False;;False;100;0;10;True;False;0,0000;False;False;1;0;10000;False;False;0;0;1;0;False;1;10000;;False;False;False;False;10.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;1000.0000;0.0000;0.0000;0.0000;0.0000;41671,8425473727;2095;;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000666-giftcard.jpg;;;;;False;ounce;;;;False;False;False;;;;;False;;;;;; +15;0;True;_SmartStore Bundle;;"

SmartStore Test Bundle

";2;False;0;;;_SmartStore Bundle;_smartstore-bundle;True;True;PD-01097;;;False;0;False;;False;False;0;False;0;1;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;888.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;41656,6659837963;"81;2095";;;;;1;;False;;;;Bestehend aus;False;False;True;;;;;False;;;;;; +15;0;True;_Bundle;;"

My product bundle.

";2;False;0;;;;_bundle;True;True;SKU-1001;;;False;0;False;;False;False;0;True;10;1;False;;False;;False;100;0;10;True;False;0,0000;False;False;1;1;9999;False;False;10;0;1;1;False;1;10000;;False;False;False;False;499.0000;0.0000;260.6000;;0.0;0.0;False;0.0000;1000.0000;0.0000;0.0000;0.0000;0.0000;41656,5811581829;"81;2095";;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000665-_bundle.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000667-_bundle.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000668-_bundle.jpg;2;;False;kg;3.0000;1;Bestehend aus;False;False;True;P-6000,P-2930,P-2940,P-2950;;;;False;;;;;; +10;0;True;_Gruppenprodukt;Grouped product;"

Tortor dis facilisis augue eros. Porta turpis! Augue! Magna mattis porttitor aliquet eu, montes magna nunc pulvinar hac, augue porttitor, ridiculus! Pulvinar, in tortor risus in scelerisque platea, pulvinar pid! Dapibus proin diam. Pellentesque cum! Tincidunt, tempor a magna turpis, mid amet, aenean, placerat. Phasellus? Tempor, cursus lacus porttitor ac, in tincidunt sociis vel? Eu velit dapibus integer enim risus augue phasellus odio turpis, sociis, eros dapibus et sed auctor, nec nisi montes, egestas integer eu rhoncus tortor integer montes sit scelerisque nec integer! Vel aliquet vut aliquet dis integer sed urna lectus sed habitasse etiam! Nunc purus augue dictumst, lectus platea? Turpis montes cras ultricies, adipiscing? Nunc. Cursus in! In ultricies parturient etiam augue, tempor mauris pellentesque purus rhoncus.

Vut vut et amet, phasellus? Et in integer enim, aenean elit, montes cum elementum nascetur a penatibus! Ac magna lorem ac placerat, lectus. Scelerisque habitasse elementum sociis scelerisque rhoncus. Natoque mattis parturient tempor dictumst turpis, hac placerat dolor nunc penatibus. Facilisis tristique massa facilisis? Rhoncus habitasse sit! Aenean aliquet ut quis ut in amet ut, phasellus augue sit tempor nunc dictumst eu, porta amet augue, mattis facilisis ac! Turpis egestas ridiculus, lacus in, sed placerat, odio lundium tincidunt nisi amet rhoncus. Augue cras! Velit, mattis! Auctor nisi mus? Amet nunc elementum placerat vut! Porttitor pid porta amet sit magnis, nisi ut cursus. Egestas sed auctor amet nec sit dapibus amet dis? Odio velit ac, hac cum ridiculus, amet ac.

Integer nisi natoque dictumst, facilisis! Phasellus turpis, pellentesque in! Dictumst pid, nisi a porttitor nec. Nunc natoque magnis etiam odio a diam vut integer aenean magnis cum lundium aenean, risus scelerisque, penatibus! Enim enim, scelerisque non placerat ut auctor, ac parturient auctor tincidunt, porttitor a est sit, nascetur scelerisque lorem in turpis sagittis mus! Enim turpis hac dis? Sit, porta nunc rhoncus ac? Integer tincidunt est porttitor, tincidunt natoque facilisis, facilisis, hac lorem elementum pulvinar tincidunt odio, dignissim cursus, urna auctor magna aliquam! Dolor duis ac tincidunt, magna! A! Urna, enim nascetur cursus, tincidunt aenean ac dis odio vel, ut lacus, duis sed in porttitor massa penatibus enim penatibus integer, augue urna scelerisque nunc elementum tincidunt duis tortor etiam.

Parturient pulvinar, lacus ut ultrices rhoncus massa! Velit et elementum pulvinar. Urna, magna integer. Nunc hac rhoncus? Amet eu? Sit in ac tortor. Lundium, pulvinar porttitor, tortor! Eros eu. Enim velit tristique elementum? Risus auctor tincidunt vut phasellus pellentesque! Turpis rhoncus vut, purus vel. Nunc ac augue! Ac sagittis pulvinar, in, duis adipiscing, velit sagittis? Penatibus mus scelerisque, nec! Dapibus scelerisque, augue turpis aenean, platea, urna integer risus a aliquet sagittis mid est elementum. Scelerisque? Tincidunt, vel vel natoque. Proin pulvinar sed placerat, cum amet nascetur scelerisque penatibus, ut, amet mus, duis placerat ac mus nec turpis facilisis dolor. Ultrices platea! Et magna enim rhoncus adipiscing odio, platea velit. Purus nunc duis! Enim velit integer facilisis nec? Diam mus.

Habitasse purus, sed vut cras non porta tincidunt facilisis, tristique, urna integer risus risus magna dictumst dignissim etiam mid! Vut risus lacus placerat, nunc a tincidunt, sociis est elementum, rhoncus pid, ridiculus quis nunc? In est scelerisque dignissim proin tortor sed, quis aenean! Et placerat in vut, risus! Augue. Lundium pid. Sit elit! Sed lorem mus ac pulvinar sit integer odio dignissim montes, adipiscing magna adipiscing porta nunc nascetur sit. Quis tortor ridiculus, in, vut tincidunt urna mus, pulvinar a! Enim arcu nec ultricies lacus sagittis mattis mauris dictumst, magna amet habitasse ut et ac! Ac amet dolor scelerisque. Auctor sit eu vut ac, velit massa tempor! Montes, dis odio quis, magna ac, phasellus purus scelerisque etiam odio penatibus.

Nec habitasse rhoncus. Pulvinar, et porta, porta tristique odio ut, massa! Purus phasellus eros porttitor, aliquet nascetur, montes turpis? Magna scelerisque rhoncus in dapibus, lundium porttitor, augue, ut placerat. Habitasse dictumst ac cursus pulvinar pid platea. Nascetur cum augue urna nunc? Magnis, arcu, pid pulvinar, natoque sed? In parturient porttitor facilisis mauris sed? Nec cras, urna et augue tristique, tincidunt tortor auctor non? Amet magna et aliquam sit sed, mid, augue pid massa sit tincidunt placerat placerat massa montes magna dapibus, ut pulvinar hac urna parturient nec dolor nunc, tristique nec proin amet ultricies magna, sociis vel etiam dolor? Augue vel augue rhoncus rhoncus enim pid tristique sit porta sit augue, tristique adipiscing! Dignissim, dictumst aliquam lundium rhoncus turpis.

Mattis platea mauris, etiam duis amet, phasellus massa, mattis, nunc sed massa integer etiam mid dis velit in sagittis vel? Mauris. Enim mid integer, lundium! Mid pid aenean mattis elementum, nunc dis etiam augue augue vel, vel rhoncus tincidunt purus porta pellentesque, pid eu aliquet, ultricies tempor sociis? Dolor! Ac ultrices ultricies! Nec enim! Mauris lorem duis magna tincidunt, vel cursus dis. Pellentesque, urna, mid integer et ac lectus elit velit lectus scelerisque mauris nunc. Aliquet platea adipiscing, sagittis urna dolor vel rhoncus a duis, ac nec diam tincidunt odio! Hac porttitor sed ac parturient purus mauris, urna etiam, nec diam magna pellentesque turpis placerat magnis eros ridiculus, elementum lorem, tempor natoque? Ultrices sed nec dapibus eu rhoncus penatibus? Urna.

Quis dolor elementum mauris! Ridiculus, auctor in, tortor ut risus velit pulvinar, porta urna rhoncus magna ultrices! Proin integer, cras rhoncus pid integer, nec odio ac, et? Dictumst pulvinar enim adipiscing facilisis ac mid nec? Pulvinar et non tristique! Sit pulvinar, pulvinar penatibus tincidunt, habitasse integer nunc! Tincidunt amet natoque facilisis aliquam tortor. Etiam duis tristique arcu egestas, et, sagittis nec ac aliquam pulvinar aliquet, adipiscing, nisi, sit sit, egestas risus. Ac. Adipiscing elit sit turpis in nec amet, nec in porta sed. Vel in in sit ultricies. Risus. Cum nascetur integer risus phasellus? Lacus mid auctor enim, enim scelerisque elementum vut a, diam eros sit duis, nascetur magna, est in dignissim adipiscing. Quis. Enim sociis egestas? Ut scelerisque.

Elit placerat turpis, porttitor penatibus phasellus! In magnis eros ut, turpis? Pid? Odio et et, mauris aenean, purus turpis, adipiscing aliquet sed tortor! Turpis dapibus amet augue ut turpis montes mauris aliquam! Penatibus est, sagittis amet nunc ultrices ultrices, amet massa enim aliquam vel odio? Purus turpis? Urna tincidunt! Elementum magna integer enim, porttitor sed aenean mus phasellus vut lorem in ac sociis, in aenean, est! Adipiscing placerat tristique, nec nunc risus turpis. Ut, porta tincidunt dapibus, dignissim? Rhoncus turpis, enim massa massa platea magnis augue amet? Sit, rhoncus, augue magna aenean lorem a et. Cum lorem. Ultrices, duis! Ultrices etiam augue ridiculus! Adipiscing? Egestas elementum magna pulvinar augue, porta elementum aliquet et facilisis phasellus auctor adipiscing lacus tincidunt.

Nec porta scelerisque ut ac etiam ac lorem cursus urna risus, amet egestas, tristique, etiam vut, adipiscing! Nunc cum habitasse pulvinar eros purus eros turpis in nascetur, habitasse adipiscing. Mattis. Nisi augue turpis, tortor, integer? Velit dis et, tristique augue. Scelerisque elementum adipiscing velit phasellus cras risus tincidunt ut rhoncus montes, scelerisque, ultricies. Et nascetur? Dis adipiscing. Natoque, turpis? Augue facilisis, dapibus augue? Elementum, tortor ac. Integer, nunc dictumst, diam nunc, augue nec non. Risus odio. Odio amet ultrices! Et urna nisi magna nisi nunc pulvinar habitasse facilisis in nunc velit natoque placerat rhoncus auctor? Magna pulvinar pulvinar augue, elementum adipiscing! Nascetur augue! Eros mus, nisi porta integer sed cras porttitor scelerisque. Pulvinar lorem turpis! Etiam, dictumst ac elit.

Vel augue placerat tempor nunc tortor purus, egestas ut lacus massa quis nec non odio amet, tincidunt parturient nunc urna eros turpis ridiculus cursus penatibus mattis penatibus augue sed! Montes scelerisque. Et dictumst adipiscing lundium, tristique, enim nascetur, cum? Non pellentesque! Mauris magna sit, porttitor, magnis, vel, nisi ultrices velit! Pellentesque, amet augue mid placerat dignissim ac etiam scelerisque, ultrices purus etiam enim, scelerisque sit turpis montes porta nunc cras enim. Non risus in enim mattis nunc. Etiam adipiscing porttitor. Massa, nunc ultricies placerat enim. Est phasellus egestas porttitor. Et et elementum tempor ac? Proin! Augue tempor cras, eros! Rhoncus scelerisque auctor eu eu, diam? Nunc egestas, lectus cum, scelerisque, elementum, scelerisque magna, tempor elit arcu dictumst? Dis elementum.

Nascetur, cras cras ridiculus lorem ac lectus enim proin odio sit lectus lorem dapibus enim. Ac nisi porttitor aliquet aliquam aenean non lacus, rhoncus pulvinar tempor dapibus dolor aliquam. In, in tincidunt penatibus cras et, lundium, sed turpis sit nunc odio, phasellus rhoncus urna facilisis platea adipiscing, mid etiam nascetur, enim, vut elementum, duis et ridiculus, penatibus urna non? Aliquam turpis augue phasellus risus diam egestas penatibus vel dignissim dignissim, ut! Elementum pulvinar et nascetur dapibus enim lundium hac platea scelerisque pellentesque facilisis! Quis, scelerisque pulvinar aliquet tincidunt elementum aliquam velit? Eros mid in facilisis, porttitor augue mattis ut, elementum placerat! Adipiscing ut augue! Facilisis in facilisis porttitor penatibus! Vel urna ridiculus magna, integer? Amet, penatibus cursus porttitor nisi.

";1;False;0;;;;_gruppenprodukt-2;True;True;SKU-1000;;;False;0;False;;False;False;0;True;10;1;False;;False;;False;100;0;10;True;False;0,0000;False;False;1;0;9999;False;False;0;0;1;0;False;1;10000;;False;False;False;False;0.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;41645,6860016551;"2095;1;81";;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000672-_gruppenprodukt.jpg;;;;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;_Wasser;;"

Optisch zum Verwechseln ähnlich, ebenso kompakt und leicht wie die erfolgreiche SD19, aber mit noch besserer Auflösung, präsentiert sich die brandneue AEE SD21 PRO Action-Cam. Die SD21 PRO ist eine komplette Neuentwicklung, mit Innovationen und einer Ausstattung, die es bisher in diesem Preissegment noch nicht gab.
Bei der SD21 PRO ist die Monitor-Rückwand wie auch die Fernbedienung ebenso selbstverständlich wie der aufsteckbare Zusatzakku für noch längere Power.
Für einfaches, unkompliziertes Justieren der Kamera ist ein Laserpointer integriert. Der 10-fach Digitalzoom und die hochwertige Optik garantieren für optimale Aufnahmeergebnisse bei allen Bedingungen.

Highlights SD21 PRO:

  • 1/3 Zoll CMOS-Sensor 8,0 Megapixel
  • 170° Weitwinkel-Objektiv, Blende F/3.0
  • 10x Digitalzoom
  • Automatische Belichtung und Weissabgleich
  • Externes TFT-Display mit Echtzeit-Anzeige für Video und das Abspielen aufgezeichneter Inhalte
  • Laserpointer als Aufnahmeorientierung
  • Selbst-/Zeit-Auslöser mit Kontroll-LED
  • Eingebautes Mikrofon für hochwertige Stereo-Voice-Aufnahmen
  • Wasserdichtes Gehäuse bis 60 Meter (IP68-Standard)
  • Hochleistungs-Lithium-Batterie
  • Aufsteckbarer Zusatzakku mit eigener Ladestandsanzeige - verdoppelt die Aufnahmedauer
  • Auto Stand-by zur Energieeinsparung
  • Funktionen: HD-Videoaufnahme / Foto
  • Recording MOV Videos können direkt am PC wiedergegeben oder auf Video-Websites hochgeladen werden
  • Photo 180-Grad-Umkehr-Funktion
  • Externe Micro SD/MMC-Speicherkarte, unterstützt bis max. 64GB (nicht enthalten)
  • Speicherkapazität Alarm
  • Schneller Vor- und Rücklauf, Funktion zum Überspringen von Inhalten in das nächste Segment
  • Unterstützung USB2.0
  • HDMI-Ausgang, AV-OUT-Funktion
  • Support-System: Windows 98SE/2000/Me/XP/Vista/Win 7/Mac OS

Grösse: ca. 61x43x40mm (BxHxT)

Gewicht: 88g ohne Bildschirm, 112g mit Bildschirm

Technische Daten SD21 PRO:

  • Auflösung/Sensor: 8.0M CMOS-Sensor (3200 * 2400)
  • Optik / Linse: 170° Weitwinkel-Objektiv, Blende F/3.0
  • Gehäuse: IP68 wasserdichtes Gehäuse bis 60m
  • Memory-Karte: Micro SD unterstützt bis 64GB (nicht enthalten)
  • Photo-Modus: 3M (2048 * 1536) / 5M (2560 * 1920) / 8M (3200 * 2400)
  • Video-Aufnahmemodus: 1080P 720P WVGA QVGA
  • Bildrate: 1080P/30fps 720P/30fps WVGA/60fps QVGA/30fps
  • Video-Aufnahmeformat: MOV (H.264-Video-Kompression)
  • Photo-Format: JPEG
  • Aufnahmekapazität (2GB SDKarte):
  • Photos 3M (1900pcs), 5M (1160pcs), 8M (770pcs) /
  • Videos: 720P/60min, WVGA/135min
  • Laserpointer/Laserleistung: 1MW
  • AV OUT: Unterstützung NTSC / PAL VGA und HDMI
  • USB: USB2.0
  • Mikrofon: 2 Mikrofone, eingebaute
  • Leistungsaufnahme: 500mA@3.7V (MAX)
  • Lithium-Batterie: 1000mAh
  • Batterielaufzeit: 2.5h / Batterie
  • Betriebssystem: Windows XP SP2/Vista oder höher / Mac OS. CPU:
  • Pentium4 1.5GHZ oder höher RAM: min. 1GB
  • RTC-Funktion: Unterstützung
  • Lagertemperatur: -20 bis -60 
  • Betriebstemperatur: -10 bis -50 
  • Luftfeuchtigkeit bei Betrieb: 15 85% RH

 

";2;True;0;;;_Wasser;_wasser;True;True;;;;False;0;False;;False;False;0;False;0;1;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;2;0;False;False;0;0;1;0;False;1;10000;;False;True;False;False;0.9900;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;41540,3761458333;"1;2095";;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000673-_wasser.jpg;;;2;;True;l;35.0000;100;;False;False;False;;;;1;True;;;;;; +5;0;True;Apple MacBook Pro MD313D/A 13,3 Zoll Notebook;3 GB, 18 Zoll, 500 GB, Intel, 4;"
Apple MacBook Pro MD313D/A 13,3 Zoll Notebook
Intel Core i5  2x 2,40 GHz
 
Bis zu 2x schnellere Prozessoren. Bis zu 3x schnellere Grafik.
Quad-Core und Dual-Core Intel Prozessoren der nächsten Generation.
Das 13"" MacBook Pro gibt es jetzt mit einem 2,4 GHz Intel Core i5 Prozessor oder dem schnellsten Dual-Core Prozessor, den es gibt: dem 2,8 GHz Intel Core i7. Diese Prozessoren bieten Turbo Boost Geschwindigkeiten und machen das 13"" MacBook Pro bis zu doppelt so schnell wie die Vorgängergeneration.
 
Aber nur schnell ist uns nicht genug. Deshalb bieten die neuen 15"" und 17"" Modelle Quad-Core Leistung für praktisch alles, was du machen willst. Auch ein 2,4 GHz Quad-Core Intel Core i7 Prozessor mit Turbo Boost Geschwindigkeiten und bis zu 8 MB gemeinsam genutztem L3-Cache ist verfügbar. Auf MacBook Pro Modellen mit diesem Prozessor laufen Programme bis zu doppelt so schnell wie auf der besten Vorgängerkonfiguration.
 
Die Grafikleistung, die du brauchst, wenn du sie brauchst.
Alle MacBook Pro Modelle haben jetzt einen integrierten Intel HD Graphics 3000 Prozessor für die täglichen Aufgaben. Er codiert Videos schnell, ermöglicht HD Videotelefonate mit FaceTime und vieles mehr. Und auch Decodieren erledigt er effizienter, was bedeutet, dass du richtig lange DVDs und iTunes Filme schauen kannst.
 
Bei anspruchsvollen Grafikprogrammen wechseln die 15"" und 17"" MacBook Pro Modelle automatisch den Grafikprozessor und arbeiten mit den neuen leistungsstarken AMD Radeon Grafikprozessoren. Diese bieten verglichen mit den Vorgängermodellen die bis zu 3-fache Leistung.3 So siehst du bei 3D Spielen mehr Bilder pro Sekunde oder kannst schneller als je zuvor an HD Videoprojekten arbeiten.
 
Das neue Thunderbolt. Die schnellste, vielseitigste I/O Technologie in einem Notebook.
Stell dir vor, du könntest auf deinem Notebook auf mehrere unkomprimierte HD Videostreams zugreifen - und zwar so schnell, dass du einen HD Spielfilm in Echtzeit schneiden kannst. Thunderbolt macht genau das möglich. Mit Thunderbolt lassen sich superschnelle Peripheriegeräte der nächsten Generation an die Computer der nächsten Generation anschließen - angefangen beim MacBook Pro. Die Thunderbolt Pipeline ist ultraschnell und ultraflexibel. Sie ist über 12 Mal schneller als FireWire 800 und bis zu 20 Mal schneller als USB 2.0. Und sie bietet beispiellose Erweiterungsmöglichkeiten. Kurzum: Sie verändert alles, was du auf deinem Notebook machen kannst.
 
Der Thunderbolt Anschluss gibt dir Plug&Play Anschluss für eine völlig neue Welt von Thunderbolt Peripheriegeräten sowie für das Apple LED Cinema Display und andere Mini DisplayPort Peripheriegeräte. Du kannst bis zu sechs Thunderbolt Geräte in Reihenschaltung anschließen, darunter auch dein Display. Außerdem unterstützt Thunderbolt Video und Achtkanal-Audio, sodass es auch möglich ist, HDMI-kompatible Geräte wie Fernseher oder Stereoanlagen über einen HDMI-Adapter anzuschließen. Auch aktuelle VGA-, DVI- und DisplayPort Adapter werden unterstützt.
 
Die neue FaceTime HD Kamera. Der Unterschied ist ganz klar.
Sieh mehr von deinen Freunden mit dem HD Widescreenformat - und zwar gestochen scharf. Die neue FaceTime HD Kamera bietet die dreifache Auflösung der vorherigen Kamera, was perfekt für das brillante Display mit LED-Hintergrundbeleuchtung ist. Außerdem arbeitet sie jetzt bei schwachem Licht noch besser. Du kannst mit deinen Freunden HD Telefonate in 720p von einem neuen MacBook Pro zu einem anderen führen. Außerdem sind auch Videotelefonate zu anderen Macs mit Intel Prozessor5, zum iPhone 4 oder zum neuen iPod touch möglich.
 
Multi-Touch Trackpad. Fürs tägliche Handwerk.
Mit dem Multi-Touch Trackpad interagierst du auf ganz natürliche Art mit den Inhalten auf deinem Display. Und die glatte Glasoberfläche bietet jede Menge Platz für Gesten. Durch Auf- und Zuziehen kannst du ein- und auszoomen, durch Streichen in deinen Fotos blättern, durch Drehen ein Bild anpassen und vieles mehr. Das Trackpad kommt ohne Taste aus, sodass du überall klicken kannst. Wenn du aus der Welt des rechten Mausklicks kommst, kannst du diesen entweder mit zwei Fingern auslösen, oder du konfigurierst einen physischen Rechtsklick-Bereich auf dem Trackpad. Je mehr du mit dem Multi-Touch Trackpad vertraut bist, desto mehr wirst du dich fragen, wie du jemals ohne ausgekommen bist.
 
Lange Laufzeit. Weniger aufladen. Mehr machen.
Das neue MacBook Pro bietet eine fantastische Batterielaufzeit und das mit leistungsstärkeren Prozessoren und schnelleren Grafikprozessoren. Die energieeffiziente Prozessorarchitektur mit integriertem Video-Encoder sowie das automatische Umschalten zwischen den Grafikprozessoren bei den 15"" und 17"" Modellen helfen, die Batterielaufzeit weiter zu verbessern. So kannst du pro Ladung bis zu 7 Stunden ohne Kabel im Web surfen6 oder es für Liveauftritte oder auf ein Shooting mitnehmen. Die fortschrittlichen chemischen Eigenschaften und die Adaptive Charging Technologie sorgen dafür, dass die Batterie bis zu 1000 Ladezyklen durchlaufen kann.7 Und da die Batterie des MacBook Pro bis zu fünf Jahre hält, kommt das MacBook Pro in einem Zeitraum, in dem ein herkömmliches Notebook drei Batterien verbraucht, mit nur einer aus. Das ist für die Benutzer genauso gut, wie für die Umwelt.
 
Apple verwendet eine neue, strengere Testmethode, um zu messen, welche Ergebnisse du unter realen Bedingungen erzielst, z. B. beim Surfen in einem Café oder wenn du die neuesten Webvideos ansiehst. Und wie schneidet dieses MacBook Pro dabei verglichen mit der Vorgängergeneration ab? Es liefert die gleiche fantastische Leistung.
 
Hat beste Verbindungen.
Unterwegs hast du mit der 802.11n Technologie im MacBook Pro immer Verbindung.8 Das MacBook Pro findet automatisch verfügbare Netzwerke und du kannst dich mit einem Klick verbinden. Auch die drahtlose Bluetooth Technologie ist integriert, sodass du drahtloses Zubehör sofort nach dem Auspacken verwenden kannst.
 
Immer Anschluss finden.
Mit dem neuen Thunderbolt Anschluss kannst du bis zu sechs Geräte in Reihenschaltung anschließen, darunter auch dein Display. So bekommst du eine vollwertige Workstation. Für die Anbindung von iPad, iPod, iPhone, Digitalkameras und externen Festplatten gibt es zwei USB 2.0 Anschlüsse (drei beim 17"" MacBook Pro) und einen FireWire 800 Anschluss.
 
Der neue SDXC Kartensteckplatz der 13"" und 15"" MacBook Pro Modelle unterstützt bis zu 64 GB Karten und macht es leicht, alle deine Fotos auf und von deinem MacBook Pro zu übertragen, damit du sie sofort bearbeiten und teilen kannst. Und der ExpressCard/34 Steckplatz am 17"" MacBook Pro ist perfekt für einen eSATA Adapter geeignet oder sogar für eine 3G Karte für die drahtlose Kommunikation, wenn kein Wi-Fi Netzwerk vorhanden ist.
 
DVDs superschnell brennen.
Homevideos, die du mit iMovie und iDVD gemacht hast, kannst du mit dem 8-fach SuperDrive Laufwerk des MacBook Pro superschnell auf eine DVD brennen. Das SuperDrive kann auch Double-Layer-DVDs (also DVDs mit fast 9 GB Speicherplatz) beschreiben, sodass es auch hervorragend für Datensicherungen geeignet ist.
";2;False;0;;;Apple MacBook Pro MD313D/A 13,3 Zoll Notebook;apple-macbook-pro-md313da-133-zoll-notebook-2;True;True;PD-01095;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;1099.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;41389,3991782407;5;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000456-apple-macbook-pro-md313da-133-zoll-notebook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000457-apple-macbook-pro-md313da-133-zoll-notebook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000458-apple-macbook-pro-md313da-133-zoll-notebook.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Apple MacBook Pro MC721D/A 15,4 Zoll Notebook;3 GB, 16 Zoll, 350 GB, AMD, 4;"
Apple MacBook Pro MC721D/A
Intel Core i7 2635QM, 2 GHz

Unibody-Gehäuse. Am Anfang jedes MacBook Pro steht ein Werkstück aus Aluminium.Stark, leicht und schön in einem.
Das MacBook Pro ist aus einem einzigen Aluminiumblock gefertigt - eine technische Meisterleistung, bei der viele Bauteile durch ein einziges ersetzt werden. Das Ganze nennt sich Unibody. Gleich beim ersten Mal, wenn Sie ein MacBook Pro in der Hand haben, werden Sie den Unterschied spüren. Das Gehäuse ist dünner und leichter als andere Notebooks. Es sieht elegant aus. Und es fühlt sich stabil und robust an: perfekt für die Aktentasche, den Rucksack und natürlich auch für draußen.
 
Ein Display voll brillanter Ideen.
Alles, was Apple Designer und Ingenieure tun, ist von A bis Z durchdacht. Sie entschieden sich beim MacBook Pro für die LED-Hintergrundbeleuchtung, weil das Display damit sofort seine volle Helligkeit erreicht und trotzdem unglaublich dünn ist. Sie verwendeten eine durchgehende Oberfläche aus Glas, nicht nur weil es schön aussieht, sondern weil es dem ganzen Display Struktur verleiht. Und über dem Bildschirm haben sie die neue, integrierte FaceTime HD Kamera versteckt. So siehst du Freunde und Familie im Großformat - und dabei so gut wie nichts von der Kamera.
 
Magnetverschluss
Da der magnetische Verschluss keine beweglichen Teile hat, die abbrechen können oder an denen man hängen bleibt, ist das Öffnen und Schließen so einfach wie alles beim MacBook Pro.
 
Einfach auf alle Anschlüsse zugreifen.
Alle Anschlüsse am MacBook Pro - der MagSafe Netzanschluss, der Gigabit Ethernetanschluss, der Thunderbolt Anschluss, der USB Anschluss, der Karten-Steckplatz und der Audioeingang und -ausgang - sind ganz auf einer Seite des Notebooks integriert. So bleiben die Kabel schön geordnet und Geräte lassen sich schnell und einfach anschließen und auch wieder trennen.
 
Hinterlässt Eindruck. Aber nicht auf die Umwelt.
Weil Apple die vollständige Kontrolle über Design, Fertigung und Verpackung des MacBook Pro hat, hat Apple einen Vorsprung beim Umweltschutz. Die Technologie zur Hintergrundbeleuchtung des Displays spart Energie. Glas und Aluminium sind besonders recyclingfähig. Das MacBook Pro kommt fast ohne Giftstoffe aus. Und die Verpackung des 39,11 cm / 15,4"" Modells ist im Vergleich zum Vorgängermodell 34 Prozent kleiner. Das bedeutet nicht nur, dass für die Verpackungen weniger Bäume gefällt werden, es werden für den Transport auch weniger Flugzeugen, Güterzügen und LKWs benötigt.
 
Thunderbolt AnschlussDie Grafikleistung, die Sie brauchen, wenn Sie sie brauchen.
Alle MacBook Pro Modelle haben jetzt einen integrierten Intel HD Graphics 3000 Prozessor für die täglichen Aufgaben. Er codiert Videos schnell, ermöglicht HD Videotelefonate mit FaceTime und vieles mehr. Und auch Decodieren erledigt er effizienter, was bedeutet, dass Sie richtig lange DVDs und iTunes Filme schauen können. Bei anspruchsvollen Grafikprogrammen wechseln die 39,11 cm / 15,4"" MacBook Pro Modelle automatisch den Grafikprozessor und arbeiten mit den neuen leistungsstarken AMD Radeon Grafikprozessoren. Diese bieten verglichen mit den Vorgängermodellen die bis zu 3-fache Leistung. So sehen Sie bei 3D Spielen mehr Bilder pro Sekunde oder können schneller als je zuvor an HD Videoprojekten arbeiten.
 
Das neue Thunderbolt. Die schnellste, vielseitigste I/O Technologie in einem Notebook.
Stellen Sie sich vor, Sie könnten auf deinem Notebook auf mehrere unkomprimierte HD Videostreams zugreifen - und zwar so schnell, dass Sie einen HD Spielfilm in Echtzeit schneiden können. Thunderbolt macht genau das möglich. Mit Thunderbolt lassen sich superschnelle Peripheriegeräte der nächsten Generation an die Computer der nächsten Generation anschließen - angefangen beim MacBook Pro. Die Thunderbolt Pipeline ist ultraschnell und ultraflexibel. Sie ist über 12 Mal schneller als FireWire 800 und bis zu 20 Mal schneller als USB 2.0. Und sie bietet beispiellose Erweiterungsmöglichkeiten. Kurzum: Sie verändert alles, was Sie auf Ihrem Notebook machen können. Der Thunderbolt Anschluss gibt Ihnen Plug&Play Anschluss für eine völlig neue Welt von Thunderbolt Peripheriegeräten sowie für das Apple LED Cinema Display und andere Mini DisplayPort Peripheriegeräte. Sie können bis zu sechs Thunderbolt Geräte in Reihenschaltung anschließen, darunter auch Ihr Display. Außerdem unterstützt Thunderbolt Video und Achtkanal-Audio, sodass es auch möglich ist, HDMI-kompatible Geräte wie Fernseher oder Stereoanlagen über einen HDMI-Adapter anzuschließen. Auch aktuelle VGA-, DVI- und DisplayPort Adapter werden unterstützt.
 
Die neue FaceTime HD Kamera. Der Unterschied ist ganz klar.
Sehen Sie mehr von Ihren Freunden mit dem HD Widescreenformat - und zwar gestochen scharf. Die neue FaceTime HD Kamera bietet die dreifache Auflösung der vorherigen Kamera, was perfekt für das brillante Display mit LED-Hintergrundbeleuchtung ist. Außerdem arbeitet sie jetzt bei schwachem Licht noch besser. Sie können mit Ihren Freunden HD Telefonate in 720p von einem neuen MacBook Pro zu einem anderen führen. Außerdem sind auch Videotelefonate zu anderen Macs mit Intel Prozessor, zum iPhone 4 oder zum neuen iPod touch möglich.
 
Multi-Touch Trackpad - Jede Menge Platz für GestenMulti-Touch Trackpad. Fürs tägliche Handwerk.
Mit dem Multi-Touch Trackpad interagieren Sie auf ganz natürliche Art mit den Inhalten auf deinem Display. Und die glatte Glasoberfläche bietet jede Menge Platz für Gesten. Durch Auf- und Zuziehen können Sie ein- und auszoomen, durch Streichen in deinen Fotos blättern, durch Drehen ein Bild anpassen und vieles mehr. Das Trackpad kommt ohne Taste aus, sodass Sie überall klicken können. Wenn Sie aus der Welt des rechten Mausklicks kommen, können Sie diesen entweder mit zwei Fingern auslösen, oder Sie konfigurieren einen physischen Rechtsklick-Bereich auf dem Trackpad. Je mehr Sie mit dem Multi-Touch Trackpad vertraut sind, desto mehr werden Sie sich fragen, wie Sie jemals ohne ausgekommen sind.
 
Lange Laufzeit. Weniger aufladen. Mehr machen.
Das neue MacBook Pro bietet eine fantastische Batterielaufzeit und das mit leistungsstärkeren Prozessoren und schnelleren Grafikprozessoren. Die energieeffiziente Prozessorarchitektur mit integriertem Video-Encoder sowie das automatische Umschalten zwischen den Grafikprozessoren bei den 39,11 cm / 15,4"" Modellen helfen, die Batterielaufzeit weiter zu verbessern. So können Sie pro Ladung bis zu 7 Stunden ohne Kabel im Web surfen oder es für Liveauftritte oder auf ein Shooting mitnehmen. Die fortschrittlichen chemischen Eigenschaften und die Adaptive Charging Technologie sorgen dafür, dass die Batterie bis zu 1000 Ladezyklen durchlaufen kann. Und da die Batterie des MacBook Pro bis zu fünf Jahre hält, kommt das MacBook Pro in einem Zeitraum, in dem ein herkömmliches Notebook drei Batterien verbraucht, mit nur einer aus. Das ist für die Benutzer genauso gut, wie für die Umwelt. Apple verwendet eine neue, strengere Testmethode, um zu messen, welche Ergebnisse Sie unter realen Bedingungen erzielen, z. B. beim Surfen in einem Cafe oder wenn Sie die neuesten Webvideos ansehen. Und wie schneidet dieses MacBook Pro dabei verglichen mit der Vorgängergeneration ab? Es liefert die gleiche fantastische Leistung.
 
Hat beste Verbindungen.
Unterwegs haben Sie mit der 802.11n Technologie im MacBook Pro immer Verbindung. Das MacBook Pro findet automatisch verfügbare Netzwerke und Sie können sich mit einem Klick verbinden. Auch die drahtlose Bluetooth Technologie ist integriert, sodass Sie drahtloses Zubehör sofort nach dem Auspacken verwenden können.
 
DVDs superschnell brennen.
Homevideos, die Sie mit iMovie und iDVD gemacht haben, können Sie mit dem 8-fach SuperDrive Laufwerk des MacBook Pro superschnell auf eine DVD brennen. Das SuperDrive kann auch Double-Layer-DVDs (also DVDs mit fast 9 GB Speicherplatz) beschreiben, sodass es auch hervorragend für Datensicherungen geeignet ist.
 
Neue Intel Core i7 Prozessoren.
Neue Quad-Core Intel Core i7 Prozessoren sind Standard beim 39,11 cm / 15,4"" MacBook Pro. Alle Modelle verwenden die kürzlich optimierten Chipsets von Intel. Was heißt das für die neuen MacBook Pro Modelle? Kurz gesagt: Sie sind bis zu zwei Mal schneller als die Vorgängergeneration und erledigen auch anspruchsvolle Aufgaben wie HD Videoschnitt, Audiokompilierung oder Rendering mehrschichtiger Bilddateien unglaublich schnell. Und da Mac OS X Snow Leopard darauf ausgelegt ist, jeden Prozessorkern zu nutzen, holt das Betriebssystem wirklich alles an Leistung aus dem Prozessor heraus.
 
Schnellere Einzelchip-Mikroarchitektur.
Ob Sie einen Film ansehen, Ihren Blog auf den neuesten Stand bringen oder Fotos bearbeiten - die Daten müssen von A nach B gelangen, um verarbeitet werden zu können. Die neueste Intel Core Architektur bringt den Prozessor, den Cache, den Speichercontroller und den Grafikprozessor auf einem einzigen Chip unter. Deswegen müssen die Daten keine weiten Wege zurücklegen, was für Sie schnellere Performance und höhere Effizienz bedeutet.
 
Turbo Boost 2.0.
Angenommen, Sie arbeiten mit einem prozessorintensiven Programm wie Aperture 3 oder Final Cut Pro, das von einem Leistungsschub profitiert würde. Turbo Boost ist eine dynamische Technologie, die automatisch die Geschwindigkeit der aktiven Prozessorkerne auf 3,4 GHz erhöht. Turbo Boost 2.0 ist noch dynamischer und effizienter. Es wechselt die Kernfrequenz in kleineren Schritten als bisher, sodass der Prozessor die Leistung ohne Effizienzeinbußen verwalten kann. All das passiert im Hintergrund. Sie arbeiten einfach nur schneller.
 
Hyper-Threading.
Hyper-Threading ist jetzt Standard auf jedem MacBook Pro. Mit dieser Technologie können auf jedem Kern zwei Threads gleichzeitig laufen, Mac OS X erkennt also bei einem Quad-Core Prozessor acht und bei einem Dual-Core Prozessor vier virtuelle Kerne. Wenn Sie mehrere Programme gleichzeitig verwenden, verteilt der Prozessor die Aufgaben gleichmäßiger über eine größere Anzahl Kerne.
 
Integrierter Speichercontroller.
Mit schnellerem Speicherzugriff legt jeder Kern direkt mit der Verarbeitung der Daten los, statt auf ihr Eintreffen zu warten. Genau deshalb nutzt die neue Intel Core Architektur einen integrierten Speichercontroller, der den schnellen 1333 MHz Speicher direkt mit dem Prozessor verbindet und Ihre Programme immer die maximale Prozessorleistung zur Verfügung haben.
 
Energieeffiziente Grafik.
Dank der neuen Mikroarchitektur ist der Grafikprozessor auf dem gleichen Chip wie der Zentralprozessor und hat direkten Zugriff auf den L3-Cache. Kurze Wege bedeuten mehr Leistung. Der Grafikprozessor erhöht auch automatisch die Taktrate für noch höhere Auslastung. Ein integrierter Video-Encoder ermöglicht jetzt HD Videotelefonate mit FaceTime, und der effiziente Decoder sorgt für lange Batterielaufzeit, wenn Sie sich DVDs oder iTunes Filme ansiehen.
 
Mac OS X. Das fortschrittlichste Betriebssystem der Welt.
Mac OS X ist das Herz jedes MacBook Pro und Mac. Dieses Betriebssystem ist genau auf die integrierten Intel Multicore-Prozessoren und fortschrittlichen Grafikprozessoren zugeschnitten. Die neueste Version, Mac OS X Snow Leopard, basiert komplett auf einer 64-Bit-Architektur, genau wie alle anderen Programme, die mit dem Mac kommen. Das bedeutet: Alles, was Sie auf Ihrem MacBook Pro machen, passiert superschnell und mit einer unglaublichen Gesamtleistung.
 
Hat eine ganze Menge draufProgramme, ebenso leistungsstark wie benutzerfreundlich.
Weil Apple sowohl das MacBook Pro, wie auch die integrierte Software entwickelt, arbeitet alles perfekt zusammen. Und mit den Apple Programmen sind Sie ganz schnell vertraut, weil alle ähnlich funktionieren. Das heißt, wenn Sie ein Programm kennen, sind Sie auch schnell mit allen anderen vertraut. Außerdem weiß Apple genau, was mobile Produktivität bedeutet. Darum haben wir Funktionen wie Expose und Spaces hinzugefügt. Damit können Sie ganz einfach auf alles auf Ihrem MacBook Pro zugreifen. Expose zeigt sämtliche geöffneten Fenster nebeneinander, verkleinert sie und ordnet sie so, dass Sie den Inhalt jedes Fensters sehen können - ein Tastendruck oder eine Geste genügt. Und mit Spaces können Sie Fenster zusammen auf ihrem eigenen Schreibtisch oder Bereich gruppieren und ganz einfach zwischen diesen wechseln. Legen Sie einen Bereich zum Arbeiten fest, einen zum Spielen und einen für was auch immer. Mit Expose und Spaces haben Sie beim Multitasking auf einem Notebookdisplay einen riesigen Vorteil.
 
Darauf verzichten Sie beim Mac: PC-Viren.
Trojaner, Würmer, E-Mail Viren. Die digitale Welt kann ganz schön beängstigend sein. Zum Glück ist der Mac immun gegen die tausenden von Viren, die Windows Computer plagen. Denn Mac OS X kommt mit integrierten Sicherheitsmechanismen, die Sie schützen - ohne dass Sie etwas machen müssen. Und sollten doch mal potenzielle Sicherheitsrisiken auftreten, reagiert Apple sofort und stellt neue Softwareaktualisierungen und Sicherheitsverbesserungen bereit, die Sie automatisch laden und mit einem Klick installieren können.
 
Das automatische Backup rettet Ihren Tag. Und die Woche, den Monat ...
Backups müssen sein. Trotzdem vergissen Sie sie bestimmt hin und wieder. Deshalb kümmert sich jetzt das MacBook Pro um die Datensicherung. Time Machine, ein Programm, das auf jedem Mac dabei ist, sichert automatisch Ihr ganzes System auf einer externen Festplatte oder Time Capsule. Time Machine speichert eine Kopie von jeder Datei. Und es merkt sich, wie Ihr System an einem bestimmten Tag ausgesehen hat. So können Sie, wenn Sie wollen, die Zeit zurückdrehen und Ihren Mac wie in der Vergangenheit sehen.
 
Mit iMovie können Sie aus Ihren Videos großartige Filme machenAuch die täglichen Sachen machen mehr Spaß.
Anders als viele PC-Notebooks kommt das MacBook Pro mit allem, was Sie brauchen, um E-Mails zu senden, Kalender zu verwalten, Kontakte zu organisieren und mehr. Und Sie können schon wenige Minuten nach dem Auspacken damit loslegen. Denn jeder Mac kommt mit Mail, um E-Mails zu senden und empfangen, iCal zum Organisieren von Terminen und wichtigen Ereignissen, dem Adressbuch zum Verwalten von Kontakten, iTunes für alles, was mit Unterhaltung zu tun hat, und weiteren tollen und nützlichen Programmen, die Sie jeden Tag verwenden werden.
 
Der Mac App Store. Tausend weitere Gründe, den Mac zu lieben.
Über tausend Mac Apps sind nur einen Klick entfernt - im Mac App Store. Suchen Sie einfach Apps, die Ihnen gefallen, und klicken Sie einfach, um sie zu laden und zu installieren. Ohne Verpackung. Ohne CDs oder DVDs. Und ohne Probleme. Sie können die Apps nach Kategorien durchstöbern oder direkt etwas Bestimmtes suchen. Und Sie können einfach dafür sorgen, dass Ihre Apps up-to-date sind, denn Ihr Mac zeigt Ihnen an, wann Updates verfügbar sind.
 
iPhoto. Fotos ganz einfach verwalten, bearbeiten und teilen.
iPhoto ist ein benutzerfreundliches Programm für Fotos, mit dem Sie Ihre Bilder schnell organisieren, wiederfinden und verbessern können - sodass sie immer perfekt aussehen. Mit den iPhoto Funktionen ""Gesichter"", ""Orte"" und ""Ereignisse"" behalten Sie den Überblick über Ihre Fotos. Sie sagen Ihnen, wen Sie fotografiert haben, wo und wann. Und all das in den neuen Vollbildmodi.
 
iMovie. Und aus Homevideos werden Home-Blockbuster.
Homevideos müssen nicht langweilig sein. Mit iMovie können Sie aus Ihren Videos großartige Filme machen. Zum Beispiel Trailer im Hollywoodstil, mit denen Sie Ihr Publikum begeistern.
 
GarageBand. Großartige Musik machen, ganz einfachissimo.
Egal, ob Sie Musiktalent haben oder einfach nur neugierig sind - GarageBand ist genau das richtige Programm für Sie. Schließ einfach eine elektrische Gitarre oder ein USB Keyboard an. Und schon können Sie mit virtuellen Nachbildungen der bekanntesten Amps und Stompboxes der Welt sowie mit 100 Software-Instrumenten spielen.
";2;False;0;;;Apple MacBook Pro MC721D/A 15,4 Zoll Notebook;apple-macbook-pro-mc721da-154-zoll-notebook-2;True;True;PD-01093;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;1483.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;41389,3991666667;5;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000545-apple-macbook-pro-mc721da-154-zoll-notebook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000546-apple-macbook-pro-mc721da-154-zoll-notebook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000547-apple-macbook-pro-mc721da-154-zoll-notebook.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Apple MacBook Pro MC725D/A 17 Zoll Notebook;4 GB, 17 Zoll, 500 GB, Tantel, 3;"
Apple MacBook Pro MC725D/A
Intel Core i7 2720QM, 2,2 GHz
 
Stark, leicht und schön in einem.
Das MacBook Pro ist aus einem einzigen Aluminiumblock gefertigt - eine technische Meisterleistung, bei der viele Bauteile durch ein einziges ersetzt werden. Das Ganze nennt sich Unibody. Gleich beim ersten Mal, wenn Sie ein MacBook Pro in der Hand haben, werden Sie den Unterschied spüren. Das Gehäuse ist dünner und leichter als andere Notebooks. Es sieht elegant aus. Und es fühlt sich stabil und robust an: perfekt für die Aktentasche, den Rucksack und natürlich auch für draußen.
 
Ein Display voll brillanter Ideen.
Alles, was Apple Designer und Ingenieure tun, ist von A bis Z durchdacht. Sie entschieden sich beim MacBook Pro für die LED-Hintergrundbeleuchtung, weil das Display damit sofort seine volle Helligkeit erreicht und trotzdem unglaublich dünn ist. Sie verwendeten eine durchgehende Oberfläche aus Glas, nicht nur weil es schön aussieht, sondern weil es dem ganzen Display Struktur verleiht. Und über dem Bildschirm haben sie die neue, integrierte FaceTime HD Kamera versteckt. So siehst du Freunde und Familie im Großformat - und dabei so gut wie nichts von der Kamera.
 
Magnetverschluss
Da der magnetische Verschluss keine beweglichen Teile hat, die abbrechen können oder an denen man hängen bleibt, ist das Öffnen und Schließen so einfach wie alles beim MacBook Pro.
 
Einfach auf alle Anschlüsse zugreifen.
Alle Anschlüsse am MacBook Pro - der MagSafe Netzanschluss, der Gigabit Ethernetanschluss, der Thunderbolt Anschluss, der USB Anschluss, der Karten-Steckplatz und der Audioeingang und -ausgang - sind ganz auf einer Seite des Notebooks integriert. So bleiben die Kabel schön geordnet und Geräte lassen sich schnell und einfach anschließen und auch wieder trennen.
 
Hinterlässt Eindruck. Aber nicht auf die Umwelt.
Weil Apple die vollständige Kontrolle über Design, Fertigung und Verpackung des MacBook Pro hat, hat Apple einen Vorsprung beim Umweltschutz. Die Technologie zur Hintergrundbeleuchtung des Displays spart Energie. Glas und Aluminium sind besonders recyclingfähig. Das MacBook Pro kommt fast ohne Giftstoffe aus. Und die Verpackung des 43,18 cm / 17"" Modells ist im Vergleich zum Vorgängermodell 34 Prozent kleiner. Das bedeutet nicht nur, dass für die Verpackungen weniger Bäume gefällt werden, es werden für den Transport auch weniger Flugzeugen, Güterzügen und LKWs benötigt.
 
Thunderbolt AnschlussDie Grafikleistung, die Sie brauchen, wenn Sie sie brauchen.
Alle MacBook Pro Modelle haben jetzt einen integrierten Intel HD Graphics 3000 Prozessor für die täglichen Aufgaben. Er codiert Videos schnell, ermöglicht HD Videotelefonate mit FaceTime und vieles mehr. Und auch Decodieren erledigt er effizienter, was bedeutet, dass Sie richtig lange DVDs und iTunes Filme schauen können. Bei anspruchsvollen Grafikprogrammen wechseln die 43,18 cm / 17"" MacBook Pro Modelle automatisch den Grafikprozessor und arbeiten mit den neuen leistungsstarken AMD Radeon Grafikprozessoren. Diese bieten verglichen mit den Vorgängermodellen die bis zu 3-fache Leistung. So sehen Sie bei 3D Spielen mehr Bilder pro Sekunde oder können schneller als je zuvor an HD Videoprojekten arbeiten.
 
Das neue Thunderbolt. Die schnellste, vielseitigste I/O Technologie in einem Notebook.
Stellen Sie sich vor, Sie könnten auf deinem Notebook auf mehrere unkomprimierte HD Videostreams zugreifen - und zwar so schnell, dass Sie einen HD Spielfilm in Echtzeit schneiden können. Thunderbolt macht genau das möglich. Mit Thunderbolt lassen sich superschnelle Peripheriegeräte der nächsten Generation an die Computer der nächsten Generation anschließen - angefangen beim MacBook Pro. Die Thunderbolt Pipeline ist ultraschnell und ultraflexibel. Sie ist über 12 Mal schneller als FireWire 800 und bis zu 20 Mal schneller als USB 2.0. Und sie bietet beispiellose Erweiterungsmöglichkeiten. Kurzum: Sie verändert alles, was Sie auf Ihrem Notebook machen können. Der Thunderbolt Anschluss gibt Ihnen Plug&Play Anschluss für eine völlig neue Welt von Thunderbolt Peripheriegeräten sowie für das Apple LED Cinema Display und andere Mini DisplayPort Peripheriegeräte. Sie können bis zu sechs Thunderbolt Geräte in Reihenschaltung anschließen, darunter auch Ihr Display. Außerdem unterstützt Thunderbolt Video und Achtkanal-Audio, sodass es auch möglich ist, HDMI-kompatible Geräte wie Fernseher oder Stereoanlagen über einen HDMI-Adapter anzuschließen. Auch aktuelle VGA-, DVI- und DisplayPort Adapter werden unterstützt.
 
Die neue FaceTime HD Kamera. Der Unterschied ist ganz klar.
Sehen Sie mehr von Ihren Freunden mit dem HD Widescreenformat - und zwar gestochen scharf. Die neue FaceTime HD Kamera bietet die dreifache Auflösung der vorherigen Kamera, was perfekt für das brillante Display mit LED-Hintergrundbeleuchtung ist. Außerdem arbeitet sie jetzt bei schwachem Licht noch besser. Sie können mit Ihren Freunden HD Telefonate in 720p von einem neuen MacBook Pro zu einem anderen führen. Außerdem sind auch Videotelefonate zu anderen Macs mit Intel Prozessor, zum iPhone 4 oder zum neuen iPod touch möglich.
 
Multi-Touch Trackpad - Jede Menge Platz für GestenMulti-Touch Trackpad. Fürs tägliche Handwerk.
Mit dem Multi-Touch Trackpad interagieren Sie auf ganz natürliche Art mit den Inhalten auf deinem Display. Und die glatte Glasoberfläche bietet jede Menge Platz für Gesten. Durch Auf- und Zuziehen können Sie ein- und auszoomen, durch Streichen in deinen Fotos blättern, durch Drehen ein Bild anpassen und vieles mehr. Das Trackpad kommt ohne Taste aus, sodass Sie überall klicken können. Wenn Sie aus der Welt des rechten Mausklicks kommen, können Sie diesen entweder mit zwei Fingern auslösen, oder Sie konfigurieren einen physischen Rechtsklick-Bereich auf dem Trackpad. Je mehr Sie mit dem Multi-Touch Trackpad vertraut sind, desto mehr werden Sie sich fragen, wie Sie jemals ohne ausgekommen sind.
 
Lange Laufzeit. Weniger aufladen. Mehr machen.
Das neue MacBook Pro bietet eine fantastische Batterielaufzeit und das mit leistungsstärkeren Prozessoren und schnelleren Grafikprozessoren. Die energieeffiziente Prozessorarchitektur mit integriertem Video-Encoder sowie das automatische Umschalten zwischen den Grafikprozessoren bei den 43,18 cm / 17"" Modellen helfen, die Batterielaufzeit weiter zu verbessern. So können Sie pro Ladung bis zu 7 Stunden ohne Kabel im Web surfen oder es für Liveauftritte oder auf ein Shooting mitnehmen. Die fortschrittlichen chemischen Eigenschaften und die Adaptive Charging Technologie sorgen dafür, dass die Batterie bis zu 1000 Ladezyklen durchlaufen kann. Und da die Batterie des MacBook Pro bis zu fünf Jahre hält, kommt das MacBook Pro in einem Zeitraum, in dem ein herkömmliches Notebook drei Batterien verbraucht, mit nur einer aus. Das ist für die Benutzer genauso gut, wie für die Umwelt. Apple verwendet eine neue, strengere Testmethode, um zu messen, welche Ergebnisse Sie unter realen Bedingungen erzielen, z. B. beim Surfen in einem Cafe oder wenn Sie die neuesten Webvideos ansehen. Und wie schneidet dieses MacBook Pro dabei verglichen mit der Vorgängergeneration ab? Es liefert die gleiche fantastische Leistung.
 
Hat beste Verbindungen.
Unterwegs haben Sie mit der 802.11n Technologie im MacBook Pro immer Verbindung. Das MacBook Pro findet automatisch verfügbare Netzwerke und Sie können sich mit einem Klick verbinden. Auch die drahtlose Bluetooth Technologie ist integriert, sodass Sie drahtloses Zubehör sofort nach dem Auspacken verwenden können.
 
DVDs superschnell brennen.
Homevideos, die Sie mit iMovie und iDVD gemacht haben, können Sie mit dem 8-fach SuperDrive Laufwerk des MacBook Pro superschnell auf eine DVD brennen. Das SuperDrive kann auch Double-Layer-DVDs (also DVDs mit fast 9 GB Speicherplatz) beschreiben, sodass es auch hervorragend für Datensicherungen geeignet ist.
 
Neue Intel Core i7 Prozessoren.
Neue Quad-Core Intel Core i7 Prozessoren sind Standard beim 43,18 cm / 17"" MacBook Pro. Alle Modelle verwenden die kürzlich optimierten Chipsets von Intel. Was heißt das für die neuen MacBook Pro Modelle? Kurz gesagt: Sie sind bis zu zwei Mal schneller als die Vorgängergeneration und erledigen auch anspruchsvolle Aufgaben wie HD Videoschnitt, Audiokompilierung oder Rendering mehrschichtiger Bilddateien unglaublich schnell. Und da Mac OS X Snow Leopard darauf ausgelegt ist, jeden Prozessorkern zu nutzen, holt das Betriebssystem wirklich alles an Leistung aus dem Prozessor heraus.
 
Schnellere Einzelchip-Mikroarchitektur.
Ob Sie einen Film ansehen, Ihren Blog auf den neuesten Stand bringen oder Fotos bearbeiten - die Daten müssen von A nach B gelangen, um verarbeitet werden zu können. Die neueste Intel Core Architektur bringt den Prozessor, den Cache, den Speichercontroller und den Grafikprozessor auf einem einzigen Chip unter. Deswegen müssen die Daten keine weiten Wege zurücklegen, was für Sie schnellere Performance und höhere Effizienz bedeutet.
 
Turbo Boost 2.0.
Angenommen, Sie arbeiten mit einem prozessorintensiven Programm wie Aperture 3 oder Final Cut Pro, das von einem Leistungsschub profitiert würde. Turbo Boost ist eine dynamische Technologie, die automatisch die Geschwindigkeit der aktiven Prozessorkerne auf 3,4 GHz erhöht. Turbo Boost 2.0 ist noch dynamischer und effizienter. Es wechselt die Kernfrequenz in kleineren Schritten als bisher, sodass der Prozessor die Leistung ohne Effizienzeinbußen verwalten kann. All das passiert im Hintergrund. Sie arbeiten einfach nur schneller.
 
Hyper-Threading.
Hyper-Threading ist jetzt Standard auf jedem MacBook Pro. Mit dieser Technologie können auf jedem Kern zwei Threads gleichzeitig laufen, Mac OS X erkennt also bei einem Quad-Core Prozessor acht und bei einem Dual-Core Prozessor vier virtuelle Kerne. Wenn Sie mehrere Programme gleichzeitig verwenden, verteilt der Prozessor die Aufgaben gleichmäßiger über eine größere Anzahl Kerne.
 
Integrierter Speichercontroller.
Mit schnellerem Speicherzugriff legt jeder Kern direkt mit der Verarbeitung der Daten los, statt auf ihr Eintreffen zu warten. Genau deshalb nutzt die neue Intel Core Architektur einen integrierten Speichercontroller, der den schnellen 1333 MHz Speicher direkt mit dem Prozessor verbindet und Ihre Programme immer die maximale Prozessorleistung zur Verfügung haben.
 
Energieeffiziente Grafik.
Dank der neuen Mikroarchitektur ist der Grafikprozessor auf dem gleichen Chip wie der Zentralprozessor und hat direkten Zugriff auf den L3-Cache. Kurze Wege bedeuten mehr Leistung. Der Grafikprozessor erhöht auch automatisch die Taktrate für noch höhere Auslastung. Ein integrierter Video-Encoder ermöglicht jetzt HD Videotelefonate mit FaceTime, und der effiziente Decoder sorgt für lange Batterielaufzeit, wenn Sie sich DVDs oder iTunes Filme ansiehen.
 
Mac OS X. Das fortschrittlichste Betriebssystem der Welt.
Mac OS X ist das Herz jedes MacBook Pro und Mac. Dieses Betriebssystem ist genau auf die integrierten Intel Multicore-Prozessoren und fortschrittlichen Grafikprozessoren zugeschnitten. Die neueste Version, Mac OS X Snow Leopard, basiert komplett auf einer 64-Bit-Architektur, genau wie alle anderen Programme, die mit dem Mac kommen. Das bedeutet: Alles, was Sie auf Ihrem MacBook Pro machen, passiert superschnell und mit einer unglaublichen Gesamtleistung.
 
Hat eine ganze Menge draufProgramme, ebenso leistungsstark wie benutzerfreundlich.
Weil Apple sowohl das MacBook Pro, wie auch die integrierte Software entwickelt, arbeitet alles perfekt zusammen. Und mit den Apple Programmen sind Sie ganz schnell vertraut, weil alle ähnlich funktionieren. Das heißt, wenn Sie ein Programm kennen, sind Sie auch schnell mit allen anderen vertraut. Außerdem weiß Apple genau, was mobile Produktivität bedeutet. Darum haben wir Funktionen wie Expose und Spaces hinzugefügt. Damit können Sie ganz einfach auf alles auf Ihrem MacBook Pro zugreifen. Expose zeigt sämtliche geöffneten Fenster nebeneinander, verkleinert sie und ordnet sie so, dass Sie den Inhalt jedes Fensters sehen können - ein Tastendruck oder eine Geste genügt. Und mit Spaces können Sie Fenster zusammen auf ihrem eigenen Schreibtisch oder Bereich gruppieren und ganz einfach zwischen diesen wechseln. Legen Sie einen Bereich zum Arbeiten fest, einen zum Spielen und einen für was auch immer. Mit Expose und Spaces haben Sie beim Multitasking auf einem Notebookdisplay einen riesigen Vorteil.
 
Darauf verzichten Sie beim Mac: PC-Viren.
Trojaner, Würmer, E-Mail Viren. Die digitale Welt kann ganz schön beängstigend sein. Zum Glück ist der Mac immun gegen die tausenden von Viren, die Windows Computer plagen. Denn Mac OS X kommt mit integrierten Sicherheitsmechanismen, die Sie schützen - ohne dass Sie etwas machen müssen. Und sollten doch mal potenzielle Sicherheitsrisiken auftreten, reagiert Apple sofort und stellt neue Softwareaktualisierungen und Sicherheitsverbesserungen bereit, die Sie automatisch laden und mit einem Klick installieren können.
 
Das automatische Backup rettet Ihren Tag. Und die Woche, den Monat ...
Backups müssen sein. Trotzdem vergissen Sie sie bestimmt hin und wieder. Deshalb kümmert sich jetzt das MacBook Pro um die Datensicherung. Time Machine, ein Programm, das auf jedem Mac dabei ist, sichert automatisch Ihr ganzes System auf einer externen Festplatte oder Time Capsule. Time Machine speichert eine Kopie von jeder Datei. Und es merkt sich, wie Ihr System an einem bestimmten Tag ausgesehen hat. So können Sie, wenn Sie wollen, die Zeit zurückdrehen und Ihren Mac wie in der Vergangenheit sehen.
 
Mit iMovie können Sie aus Ihren Videos großartige Filme machenAuch die täglichen Sachen machen mehr Spaß.
Anders als viele PC-Notebooks kommt das MacBook Pro mit allem, was Sie brauchen, um E-Mails zu senden, Kalender zu verwalten, Kontakte zu organisieren und mehr. Und Sie können schon wenige Minuten nach dem Auspacken damit loslegen. Denn jeder Mac kommt mit Mail, um E-Mails zu senden und empfangen, iCal zum Organisieren von Terminen und wichtigen Ereignissen, dem Adressbuch zum Verwalten von Kontakten, iTunes für alles, was mit Unterhaltung zu tun hat, und weiteren tollen und nützlichen Programmen, die Sie jeden Tag verwenden werden.
 
Der Mac App Store. Tausend weitere Gründe, den Mac zu lieben.
Über tausend Mac Apps sind nur einen Klick entfernt - im Mac App Store. Suchen Sie einfach Apps, die Ihnen gefallen, und klicken Sie einfach, um sie zu laden und zu installieren. Ohne Verpackung. Ohne CDs oder DVDs. Und ohne Probleme. Sie können die Apps nach Kategorien durchstöbern oder direkt etwas Bestimmtes suchen. Und Sie können einfach dafür sorgen, dass Ihre Apps up-to-date sind, denn Ihr Mac zeigt Ihnen an, wann Updates verfügbar sind.
 
iPhoto. Fotos ganz einfach verwalten, bearbeiten und teilen.
iPhoto ist ein benutzerfreundliches Programm für Fotos, mit dem Sie Ihre Bilder schnell organisieren, wiederfinden und verbessern können - sodass sie immer perfekt aussehen. Mit den iPhoto Funktionen ""Gesichter"", ""Orte"" und ""Ereignisse"" behalten Sie den Überblick über Ihre Fotos. Sie sagen Ihnen, wen Sie fotografiert haben, wo und wann. Und all das in den neuen Vollbildmodi.
 
iMovie. Und aus Homevideos werden Home-Blockbuster.
Homevideos müssen nicht langweilig sein. Mit iMovie können Sie aus Ihren Videos großartige Filme machen. Zum Beispiel Trailer im Hollywoodstil, mit denen Sie Ihr Publikum begeistern.
 
GarageBand. Großartige Musik machen, ganz einfachissimo.
Egal, ob Sie Musiktalent haben oder einfach nur neugierig sind - GarageBand ist genau das richtige Programm für Sie. Schließ einfach eine elektrische Gitarre oder ein USB Keyboard an. Und schon können Sie mit virtuellen Nachbildungen der bekanntesten Amps und Stompboxes der Welt sowie mit 100 Software-Instrumenten spielen.  
";2;False;0;;;Apple MacBook Pro MC725D/A 17 Zoll Notebook;apple-macbook-pro-mc725da-17-zoll-notebook-2;True;True;PD-01094;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;2299.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;41389,3991666667;5;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000312-apple-macbook-pro-mc725da-17-zoll-notebook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000313-apple-macbook-pro-mc725da-17-zoll-notebook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000314-apple-macbook-pro-mc725da-17-zoll-notebook.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Asus Eee PC 1001HA 10,1 Zoll Netbook;3 GB, 17 Zoll, 400 GB, AMDl, 3;"
Eee PC™ 1001HA: Klasse Leistung zu unschlagbarem Preis
 
Der Eee PC™ 1001HA unterscheidet sich von seinen großen Brüdern durch Prozessor und Akkukapazität. Ausgestattet mit einem Intel® Atom™ N270 Prozessor, einem 3 Zellen Akku für bis zu 4 Stunden Laufzeit, WLAN 802.11n Standard sowie weiteren Top Merkmalen, überzeugt der Eee PC™ 1001HA zu einem wirklich unschlagbaren Preis.
 
Eee PC™ 1001HA: Funktionalität meets Design
 
Mit dem kompakten Eee PC™ 1001HA trägt ASUS seinem Anspruch, in den Produkten höchste Funktionalität mit formvollendetem Design zu verbinden, ein weiteres Mal Rechnung. So besticht der neue Eee PC™ durch sein elegantes und gleichzeitig unempfindliches Gehäuse, das mit klaren Linien und nach unten schmaler zulaufenden Kanten dem schlanken Design einer Muschel nachempfunden ist. Aber auch das Innenleben der Kleinen kommt ganz groß raus. Als gewohnt kontaktfreudig erweisen sich die Neulinge dank VGA Port für den Anschluss eines Monitors sowie drei USB 2.0 Schnittstellen, um Maus, Tastatur oder Digicam anzuschließen. Wer Bilder direkt von der SD oder MMC Speicherkarte auf den Eee PC™ übertragen möchte, nutzt den integrierten Kartenleser. Für das Speichern der Fotos stehen bei beiden Modellen eine 160 GB S-ATA Festplatte zur Verfügung.. Das Modell basiert auf Microsoft® Windows® XP Home und ist – wie alle Eee Familienmitglieder – ausgesprochen einfach zu bedienen. Das 10 Zoll WSVGA Display mit stromsparender LED-Hintergrundbeleuchtung sowie die große Tastatur, die zu 92% einer Standard Notebooktastatur entspricht, gewähren zusätzlichen Komfort. Für Chats oder Videokonferenzen hat ASUS die Minis zudem mit einer 0.3 Megapixel Web-/Videokamera sowie einem Mikrofon ausgestattet.
 
 
";2;False;0;;;Asus Eee PC 1001HA 10,1 Zoll;asus-eee-pc-1001ha-101-zoll-netbook-2;True;True;PD-01090;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;243.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;41389,3988657407;5;37;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000563-asus-eee-pc-1001ha-101-zoll-netbook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000564-asus-eee-pc-1001ha-101-zoll-netbook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000565-asus-eee-pc-1001ha-101-zoll-netbook.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"HP Compaq Mini 110c-1110sg 10.1 Zoll Netbook ";4 GB, 18 Zoll, 800 GB, Intel, 2;"
HP Compaq Mini 110c-1110sg 10.1 Zoll Netbook
 
Intel Atom N270 1.6GHz, 1GB RAM, 160GB HDD, Intel GMA 950, Win XP Home
 
Leicht und kompakt
Der Compaq Mini 110c wiegt 1,3 kg (mit 6-Zellen-Akku) und ist ca. 5,5 cm hoch – er ist damit sehr kompakt und fällt ins Auge
 
Elegantes Design
Der Compaq Mini 110c glänzt mit einem eleganten Gehäuse im neuem Imprint-Finish ""Unity"", einem Karomuster, das ins Auge fällt.
 
Ständig in Verbindung
Webcam und Mikrofon sind im Compaq Mini integriert und bieten per WLAN und optionalem WWAN zahlreiche Möglichkeiten zur Pflege sozialer Kontakte; Video-Chats und Video-Konferenzen, die bislang nur zuhause möglich waren, können jetzt im Park, im Cafe oder am Flughafen geführt werden
 
Information und Kommunikation auch unterwegs
Mit dem 10,1-Zoll-BrightView-Display, Original Windows® XP Home, der großen Tastatur (92 % der vollen Größe), drei USB-Anschlüssen und einem 5-in-1 Kartenleser sind Informationen, Kommunikation und Unterhaltung im Internet überall bequem zugänglich.
";2;False;0;;;"HP Compaq Mini 110c-1110sg 10.1 Zoll Netbook ";hp-compaq-mini-110c-1110sg-101-zoll-netbook-2;True;True;PD-01091;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;259.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;41389,3988657407;"5;2095";39;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000598-hp-compaq-mini-110c-1110sg-101-zoll-netbook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000599-hp-compaq-mini-110c-1110sg-101-zoll-netbook.jpg;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Samsung NC10 anyNet 10,2 Zoll Netbook;2 GB, 15 Zoll, 400 GB, AMDl, 4;"
Samsung NC10 anyNet10,2"" Netbook

Intel Atom N270 1.6GHz, 1GB RAM, 160GB HDD, Intel GMA 950 XP Home
 
NC10-anyNet: Entwickelt für das ""mobile Leben"". Entwickelt für höchste Ansprüche in innovativem Design. Das ultrakompakte und leichte Gehäuse bietet eine Reihe von praktischen Features, die das mobile Leben vereinfachen. Brillante Technologie angepasst an das rasante und digitale Leben für noch mehr Mobilität.
 
Schlankes Design
Mit einem optimierten 10,2 Zoll Breitbild Display für ein makelloses visuelles Erlebnis, ist das schlanke NC10 lediglich 1,19 cm hoch und passt nahezu in alle Taschen. Das widerstandsfähige Gehäuse bietet ein Maximum an Tragekomfort und Verlässlichkeit sowie hochwertiger Ergonomie und Stil.
 
Videokonferenz
Ob Videokonferenzen oder Live Messaging - die integrierte 1,3 Megapixel Kamera lässt sie noch leichter mit Freunden, Familie und Kollegen in Kontakt bleiben. Die Kamera verbindet die Auflösung und die Bildqualität einer Fotokamera mit der nachhaltig hohen Bildfrequenz einer Videokamera.
 
Robustes Gehäuse, langlebig und verlässlich
Fühlen Sie sich sicher mit dem robusten Protect-o-Edge Gehäuse, das für Langlebigkeit und Verlässlichkeit steht. Eine aufwendige Serie von 54 Qualitätstests, die von schnellen Temperaturwechseln bis zu elektrischen Überspannungen reichen, gewährleistet neue Standards in Punkto Belastbarkeit und Ausdauer.
 
Antibakterielle Tastatur
Die SilverNano Technologie beschichtet die Tastatur mit nano-kleinen Silberionen, die das Überleben und die Neuentstehung von Bakterien verhindern. Innerhalb von 24 Stunden werden 99,9% aller Bakterien abgetötet und es entsteht eine hygienische Arbeitsatmosphäre.
 
Leichtgewicht
Als eines der weltweit leichtesten 10,2 Zoll Mini Notebooks seiner Klasse, mit einem Gewicht von nur 1,45 kg, ist das NC10 voll bepackt mit neuester Technologie und garantiert dabei maximale Mobilität und Leistung.
  
Vollständige Notebook-Tastatur
Die vollständige Notebook-Tastatur bietet optimalen Schreibkomfort. Ergonomisches Design und optimierte Tastenabstände machen das Arbeiten und Kommunizieren angenehmer und ermöglichen schnelleres sowie fehlerloses Schreiben.
 
Voll ausgestattet für einfachen Datenaustausch
Einfacher Datenaustausch dank einer Vielzahl an Anschlussmöglichkeiten, inklusive einem Kartenleser und drei USB-Anschlüssen, so dass Sie problemlos Bilder, Filme und Daten auf und von nahezu allen modernen Kameras, periphären oder audiovisuellen Geräten transferieren können.
";2;False;0;;;;samsung-nc10-anynet-102-zoll-netbook-2;True;True;PD-01092;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;329.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;41389,3988657407;5;5;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000511-samsung-nc10-anynet-102-zoll-netbook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000512-samsung-nc10-anynet-102-zoll-netbook.jpg;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Germot GM 205 Integralhelm Dekor;Der GM 205 ist der Preisgünstige einsteiger Motorradhelm mit kratzfestem Außenvisier.;"
Germot GM 205 Integralhelm
Ideal für Rollerfahrer oder kurze touren
 
klare, getönte und verspiegelte Visiere zu diesem Modell sind in unserem Shop erhältlich!
 
Eigenschaften: klares, kratzfestes Visier mit Verstellraster, einfacher und schneller Visierwechsel, Visier- und Kopfbelüftung, großes Gesichtsfeld, Nasenspoiler, hautfreundliche Innenausstattung, hochwertige Mehrschichtlackierung mit UV-Schutz, Drucktastensteckschloss, ECE 22 05.

Material: ABS/Polycarbonat Mix

Gewicht: 1.400g +/-50g

Größen: XS (53-54) / S (55-56) / M (57-58) / L (59-60) / XL (61-62) / 2XL (63-64)
Größenangabe in Klammer= Kopfumfang in cm.
";2;False;0;GM205, rollerhelm, integralhelm,germot,motorradhelm;Der GM 205 ist der Preisgünstige einsteiger Motorradhelm und Rollerhelm mit kratzfestem Außenvisier.;Germot GM 205 Integralhelm Dekor;germot-gm-205-integralhelm-dekor;True;True;20596;;5000111105392;False;0;False;;False;False;0;False;0;1;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;2;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;79.9000;79.9000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;41129,4577083333;"1;22";1;;;;5;;False;kg;;;;False;False;False;;;;;False;;;;;; +5;0;True;Apple iPod Nano 16 GB 6. Gen. verschiedene Farben;Apple iPod Nano 16 GB 6. Generation verschiedene Farben;"
Der Remix für Ihre Finger
Der iPod nano mit Multi-Touch ist einfach, intuitiv und macht jede Menge Spaß - wie Ihre Musik. Und er ist jetzt noch kleiner, damit Musik bei allem, was Sie machen, eine größere Rolle spielen kann.
 
Musik. Fühlen Sie den Beat
Ihre Greatest Hits. Zum Anfassen
Die besten Dinge im Leben kommen mit Soundtrack. Und genau da glänzt der iPod nano. Mit dem Multi-Touch Display können Sie Ihre Musik ganz neu erleben. Ein Tipp genügt und er spielt, was Sie hören wollen. Stöbern Sie in Ihrer Musik nach Songs, Alben, Interpreten, Wiedergabelisten, Genres oder Komponisten - streichen Sie dazu über den Homescreen. Sie können sogar die Symbole auf dem Homescreen neu ordnen, damit alles so ist, wie Sie es wollen.
 
Das ist ein echter Musikclip
Mit dem neuen integrierten Clip können Sie mit Ihren Lieblingssongs am Ärmel (oder in der Tasche, Jacke oder Hose) wandern, laufen, Rad fahren und abrocken. Und das Cover zum Song, der gerade läuft, passt perfekt auf das Display.
 
Rock around the clock
Die integrierte aufladbare Lithium-Ionen-Batterie sorgt für 24 Stunden Musik nonstop. Wenn Sie sich den 8 GB oder 16 GB iPod nano anklippen, haben Sie genug Songs für den Weg zur Arbeit, fürs Training und mehr.
 
Songs aus dem Finger schütteln
Überlassen Sie alles dem Zufall. Einfach den iPod nano kurz schütteln und er springt zu einem anderen Song aus Ihrer Sammlung. Schütteln ist perfekt, wenn Ihnen gerade nicht nach einer bestimmten Musik ist. Lassen Sie sich einfach überraschen.
 
Genius. Ihr Mixmaster
 
Eingebauter Clip

 
Ihr persönlicher DJ
Angenommen, Sie hören einen Song, der Ihnen gut gefällt, und möchten ähnliche hören. Ein Tipp auf Genius genügt. Genius findet weitere Songs auf Ihrem iPod nano, die gut dazu passen und erstellt eine Genius Wiedergabeliste für Sie. Wenn Sie einen Mix wollen, auf den Sie selbst nie gekommen wären, erstellen Sie einen Genius Mix in iTunes und synchronisieren ihn mit Ihrem iPod nano. Tippen Sie auf das Symbol für Genius Mixe und entdecken Sie Songs, die Sie lange nicht mehr gehört haben, oder Musik, von der Sie gar nicht mehr wussten, dass Sie sie haben.
 
FM Radio. Und Sie haben alles auf dem Sender
Radio nano
Mit dem iPod nano können Sie auf der Radiowelle surfen. Der FM Tuner zeigt Ihnen den Interpreten, Song oder Sender, der gerade läuft. Ein Tipp genügt und Sie sehen die Radiosteuerungen. Streichen Sie über den Tuner, um den Sender zu wechseln, und stellen Sie dann Ihre Lieblingssender per Fingertipp ein.
 
Live-Pause
Wenn Sie Ihre Lieblingssendung im Radio einmal kurz unterbrechen müssen, verpassen Sie dank Live-Pause trotzdem keinen einzigen Beat. Einfach Tippen und Sendung oder Song werden angehalten. Noch mal Tippen und es geht da weiter, wo Sie aufgehört haben. Sie können sogar bis zu 15 Minuten zurückspulen und dann vorspulen, um wieder live dabei zu sein.
 
Fitness. Treffen Sie Ihren neuen Trainer
 
Anklippen und los geht´s
Das neue Design des iPod nano hilft Ihnen fit zu bleiben. Weil er so klein und tragbar ist, ist er auch beim Joggen, Wandern und im Fitnessstudio immer dabei. Klippen Sie ihn an und steuern Sie Ihre Musik mit nur einem Tippen oder Streichen, sodass Sie sich voll auf Ihr Workout konzentrieren können. Ob Laufen, Walken oder der Weg zum Fitnessstudio - für den kleinen iPod nano ist kein Weg zu weit.
 
Schritte zum Fitbleiben
Sie können den iPod nano auch als Schrittzähler verwenden. Er zählt Ihre Schritte und hilft Ihnen beim Erreichen Ihrer Fitnessziele. Einfach anklippen und los geht´s. Sie können eine tägliche Schrittvorgabe festlegen und Ihre Fortschritte sehen, wenn Sie Ihre Daten auf die Nike+ Website laden.
 
Rocken Sie Ihr Training
Ob beim Joggen oder im Fitnessstudio, mit dem Nike + iPod Sport Kit (separat erhältlich) motiviert Sie der iPod nano vom Warm Up bis zum Cool Down. Ziehen Sie Ihre Nike+ Joggingschuhe an und klippen Sie sich den iPod nano an. Sehen Sie wie Sie Kilometer für Kilometer zurücklegen und hören Sie das Sprachfeedback in Echtzeit, während Ihre Songs laufen. Schließen Sie den iPod nano im Fitnessstudio an ein Gerät an, das mit Nike + iPod kompatibel ist. So zeichnet er Ihre Geschwindigkeit, die Dauer und die Laufstrecke auf, während Sie Ihr Training rocken.
 
iTunes. Damit der iPod was zu spielen hat
Alles für gute Unterhaltung
iTunes ist der beste Weg, Ihren iPod nano mit den neuesten Hits, Podcasts, Hörbüchern und vielem mehr zu füllen. Und auch die beste Art, Ihre immer weiter wachsende Sammlung digitaler Medien zu durchstöbern und auf dem Mac oder PC zu organisieren. Alle im iTunes Store gekauften Inhalte und alle von CDs importierten Songs werden in Ihrer Mediathek in iTunes angezeigt. Sie können Ihre eigenen oder Genius Wiedergabelisten erstellen, Genius Mixe auswählen und alles mit Ihrem iPod nano synchronisieren. Und iTunes ist als kostenloser Download verfügbar.
 
Der beste Music Store der Welt
Laden Sie Ihre Lieblingssongs auf Ihren iPod nano. Oder stöbern Sie in über 13 Millionen Songs und finden Sie weitere Hits. Sie können nach dem Namen eines Interpreten, Songs oder Albums suchen und so genau die richtigen Songs finden. Sie suchen neue Musik und brauchen Hilfe? Die Genius Seitenleiste empfiehlt Ihnen neue Musik, die auf Ihren Lieblingssongs basiert. Sie können in jeden Song kostenlos 30 Sekunden reinhören. Und mit einem Klick können Sie einen Song kaufen. Er wird dann sofort geladen. Schneller und einfacher können Sie Ihre digitale Musiksammlung für den iPod nicht zusammenstellen.
 
Bedienungshilfen
Integrierte Bedienungshilfen.
iPod nano kommt mit Bedienungshilfen, die Menschen mit Handicaps helfen Musik, Hörbücher und mehr zu erleben.
 
VoiceOver
Der iPod touch bietet VoiceOver, die weltweit erste Bildschirmlesefunktion, die auf Gesten basiert. Tippen Sie auf das Display und Sie hören eine Beschreibung des Objekts, das Sie gerade berühren. Steuern Sie den iPod nano durch Doppeltippen, Bewegen oder Streichen. Mit den optionalen Apple Earphones mit Fernbedienung und Mikrofon können Sie Ihre Musik steuern, ohne auf das Display zu sehen. VoiceOver nennt Ihnen den Song und Interpreten und spricht auch noch 29 Sprachen.
 
Weiß auf Schwarz
Wenn Sie stärkeren Kontrast möchten, stellen Sie das Display des iPod nano so ein, dass Weiß auf Schwarz angezeigt wird. Sie können diese Funktion in jeder App und auch auf dem Homescreen verwenden.
 
Mono Audio
Wenn Sie nur auf einem Ohr gut hören können, können Sie ""Mono-Audio"" aktivieren, damit die Audioausgabe auf beide Ohrhörer geleitet wird und Sie beide Kanäle mit dem gesunden Ohr hören können.

Produktbeschreibungen
 
Highlights
- Multi-Touch Display
- Genius - dein Mixmaster
- FM Radio
- iTunes
- Integrierte Bedienungshilfen (VoiceOver und Weiß auf Schwarz)
 
Akku
- Akkutyp: Li-Ion
- Akkulaufzeit bis zu 24 Stunden
 
Display
- Farbdisplay
- Bilddiagonale: 3,91 cm
- 1,54- Display
- Auflösung Breite: 240 Pixel
- Auflösung Höhe: 240 Pixel
 
Speicher
- Interner Speicher 8.000 MB
 
Stromversorgung
- USB-Lader
 
Wiedergabeformate Audio
- AAC
- MP3
- WAV
 
Grundeigenschaften
- Breite: 40,9 mm
- Höhe: 37,5 mm
- Tiefe: 8,78 mm
- Gewicht: 21,1 g
- Gewicht: 21,1 g
- Farbe: Dunkelgrau
 
Lieferumfang
- iPod nano
- Apple Earphones
-Dock Connector auf USB Kabel
- Dokumentation und wichtige Produktinformationen
";2;False;0;;;Apple iPod Nano 16 GB 6. Gen. verschiedene Farben;apple-ipod-nano-16-gb-6-gen-verschiedene-farben;True;True;PD-01087;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;179.0000;179.0000;179.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40900,5013078704;49;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000266-apple-ipod-nano-16-gb-6-gen-verschiedene-farben.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000267-apple-ipod-nano-16-gb-6-gen-verschiedene-farben.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000268-apple-ipod-nano-16-gb-6-gen-verschiedene-farben.jpg;1;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Microsoft Windows XP Professional SP3 OEM;"Microsoft Windows XP Professional SP3 OEM ";"

Microsoft Windows XP Professional SP3 OEM

auf jedem PC installierbar-OEM
 
 
Windows XP Professional ist das bewährte Windows-Betriebssystem für Unternehmen und Heimanwender.
Auf der soliden Grundlage von Windows 2000 bietet Windows XP Professional verbesserte Zuverlässigkeit,
Sicherheit, Leistung und Benutzerfreundlichkeit und setzt zugleich neue Maßstäbe in der Datenverarbeitung.
Mit den professionellen Features zur Administration und zur Netzwerkanbindung erweitert
Windows XP Professional den Funktionsumfang von Windows XP Home Edition.
Windows XP Professional basiert auf einer 32-Bit-PC-Architektur und umfasst ein vollständig geschütztes Speichermodell.
 
Dies alles macht Windows XP Professional zur zuverlässigen Version. Die Funktion ""Systemwiederherstellung""
ermöglicht es Benutzern und Systemverwaltern, den Status eines PCs wiederherzustellen, den er vor einem Ausfall hatte,  ohne dass dabei Daten verloren gehen.
Bei der Systemwiederherstellung werden problemlos erkennbare Wiederherstellungspunkte erstellt,
anhand derer Sie das System auf eine bestimmte Uhrzeit wiederherstellen können. 
";2;False;0;;;Microsoft Windows XP Professional SP3 OEM;microsoft-windows-xp-professional-sp3-oem;True;True;P-2960;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;57.9900;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40889,6330208333;"30;80";3;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000181-microsoft-windows-xp-professional-sp3-oem.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000182-microsoft-windows-xp-professional-sp3-oem.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000183-microsoft-windows-xp-professional-sp3-oem.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Windows 7 32 Bit;Windows 7 32 Bit;"
Windows 7  
 
Die umfassendste Edition von Windows 7
Windows 7 Ultimate ist die vielseitigste und leistungsfähigste Edition von Windows 7. Sie kombiniert die bemerkenswerte Benutzerfreundlichkeit der Unterhaltungsfunktionen von Home Premium mit den unternehmensorientierten Funktionen von Professional, wozu auch die Fähigkeit zum Ausführen zahlreicher Windows XP-Produktivitätsprogramme im Windows XP-Modus gehört.
 
Für mehr Sicherheit können Sie Ihre Daten auch mit BitLocker und Bitlocker To Go verschlüsseln. Und zur Erhöhung der Flexibilität können Sie in einer beliebigen von 35 Sprachen arbeiten. Mit Windows 7 Ultimate müssen Sie auf nichts verzichten.
 
Windows 7 vereinfacht alltägliche Aufgaben
 
Desktop
Unter Windows 7 ist es nun einfacher, noch mehr Aufgaben direkt auf dem Desktop zu erledigen: Verbesserte Taskleistenvorschau, größere Symbole, Anheften und kreative Möglichkeiten der Personalisierung.
 
Neue Möglichkeiten, mit Fenstern zu jonglieren
Überwältigt von der Zahl der geöffneten Fenster? Windows 7 bietet drei einfache und dennoch leistungsfähige neue Funktionen, die wie folgt bezeichnet werden: Aero Shake, Aero Peek und Snap. Sie unterstützen Sie dabei, sofort den Weg durch den Desktop zu finden.
 
 
Die verschiedenen Windows 7 Editionen im Vergleich 
 
Spektakuläre neue Hintergrundbilder
Seien wir ehrlich: Wir verbringen jede Menge Zeit damit, auf unsere PCs zu starren. Die Ästhetik sollte daher nicht zu kurz kommen. Darum enthält Windows 7 viele neue Desktophintergründe, so genannte Hintergrundbilder, unter denen sich alle möglichen Motive von beeindruckend bis unterhaltsam befinden. Oder probieren Sie doch einmal die neue Desktopdiashow aus, in der eine wiederkehrende Reihe von Bildern (unserer oder Ihrer) angezeigt wird. Desktop und langweilig? Das ist vorbei.
 
Schauen Sie sich die ""Superleiste"" an
Schon unter Windows 95 hat die Taskleiste als Ausgangspunkt zum Starten von Programmen und Umschalten zwischen Fenstern gedient. Nicht nur die Zeiten, auch die Arbeitsweisen am PC haben sich geändert. Unter Windows 7 wurde die Taskleiste daher komplett neu gestaltet, damit Sie noch mehr Aufgaben erledigen können. Sie ist ansprechender, kann besser angepasst werden und vereinfacht das Multitasking.
 
Heimnetzgruppe
Dank der Heimnetzgruppe brauchen Sie sich keine Gedanken mehr über die Datei- und Druckerfreigabe in einem Heimnetzwerk zu machen. Verbinden Sie mindestens zwei Windows 7-PCs, und schon kann mit der Heimnetzgruppe ganz einfach die automatische Freigabe von Musik, Bildern, Videos und Dokumentbibliotheken für andere Personen im Haus starten. Und das neue Menü ""Freigeben für"" ermöglicht die schnelle Freigabe einzelner Dateien.
 
Machen Sie sich Sorgen um den Datenschutz? Wir auch. Und deshalb ist die Heimnetzgruppe kennwortgeschützt, sodass Sie die volle Kontrolle über den Zugriff haben. Sie entscheiden, welche Dateien freigegeben werden und welche nicht. Außerdem können Sie Ihre Dateien mit Schreibschutz versehen, d. h., der Inhalt kann von anderen angesehen, aber nicht geändert werden. Einer Heimnetzgruppe beizutreten, ist in jeder Edition von Windows 7 möglich. Das Erstellen einer Heimnetzgruppe ist jedoch nur in den Editionen Home Premium, Professional und Ultimate möglich.
 
 
Die verbesserte Taskleiste verschafft mit Hilfe der neuen Vollbild-Vorschaufenster schnellen Überblick 
 
Sprunglisten
Über die in Windows 7 neu eingeführten Sprunglisten gelangen Sie nun direkt zu den Dokumenten, Bildern, Songs oder Websites, die Sie tagtäglich nutzen. Zum Öffnen einer Sprungliste klicken Sie auf der Taskleiste von Windows 7 einfach mit der rechten Maustaste auf ein Programm (Sie sind auch im Startmenü zu finden.).
 
Der Inhalt einer Sprungliste hängt vom Programm ab. In der Sprungliste für Internet Explorer 8 werden häufig besuchte Websites angezeigt. Windows Media Player 12 enthält häufig abgespielte Musiktitel. Fehlt in der Sprungliste ein Favorit? Sie können dort beliebige Dateien ""anheften"". In Sprunglisten werden nicht nur Verknüpfungen zu Dateien angezeigt. Manchmal bieten sie auch Schnellzugriff auf Befehle für Aufgaben wie das Verfassen neuer E-Mail-Nachrichten oder das Wiedergeben von Musik.
 
Snap
Snap bietet eine schnelle neue Möglichkeit, die Größe geöffneter Fenster einfach durch Ziehen an die Bildschirmränder zu ändern. Je nach Rand, also, oben oder unten, rechts oder links, wird das Fenster verbreitert, oder es füllt den ganzen Bildschirm aus. Und Sie können Fenster auch nebeneinander anordnen. Mit Snap wird das Lesen, das Anordnen und das Vergleichen von Fenstern zum Kinderspiel.
 
 
Den Desktop jederzeit im Blick dank transparenter Fenster 
 
Windows Live Essentials
Was ist Windows Live Essentials? Einfach ausgedrückt, handelt es sich um kostenlose Software, die einen Windows 7-PC mit noch mehr tollen Funktionen ausstattet, z. B. für E-Mail, Instant Messaging, Fotobearbeitung und Blogs. Windows Live Windows Live Essentials ist auf der Windows Live-Website verfügbar. Der kostenlose Download enthält folgende Komponenten: Messenger, Fotogalerie, Mail, Writer, Movie Maker, Symbolleiste und Family Safety.
 
Windows Search
Unter Windows 7 finden Sie noch schneller noch mehr Dinge an noch mehr Orten. Sobald Sie im Suchfeld des Startmenüs mit der Eingabe beginnen, wird eine Liste relevanter Dokumente, Bilder, Musiktitel und E-Mails auf dem PC angezeigt. Die Ergebnisse sind nun nach Kategorie gruppiert und enthalten hervorgehobene Stichwörter und Textausschnitte, um die Suche zu vereinfachen.
 
Dateien werden heutzutage nur noch selten an einem Ort abgelegt. Also ist Windows 7 auch darauf ausgelegt, externe Festplatten, Netzwerk-PCs und Bibliotheken zu durchsuchen. Zu viele Suchergebnisse? Sie können die Suche direkt nach Datum, Dateityp und anderen hilfreichen Kategorien eingrenzen.
 
Windows 7 funktioniert Ihren Vorstellungen entsprechend
 
Leistungsverbesserungen
Niemand wartet gerne. Darum ist Windows 7 nun noch schneller und immer bereit, wenn Sie es sind. Zu den wichtigen Leistungsverbesserungen zählen u. a. schneller Wechsel in und aus dem Energiesparmodus, weniger Speicherbedarf und schnelle Erkennung von USB-Geräten:
 
Standbymodus
Windows 7 kann in den Energiesparmodus versetzt und wiederhergestellt werden und die Verbindung mit dem Drahtlosnetzwerk wieder schneller herstellen.
 
 
Sprunglisten ermöglichen schnellen Zugriff auf häufig anstehende Aufgaben 
 
Suchen
Wenn Sie auf der Suche nach Informationen sind, dann möchten Sie nicht lange warten, sondern Antworten bekommen. Unter Windows 7 werden Suchergebnisse schneller angezeigt. Auch das Sortieren und Gruppieren von Suchergebnissen geht viel rascher vonstatten.
 
USB-Geräte
Wenn Sie zum ersten Mal ein tragbares Flashlaufwerk oder ein anderes USB-Gerät anschließen, stellt Windows 7 es innerhalb weniger Sekunden für Sie bereit. Und wenn Sie es bereits zuvor verwendet haben, dann geht es sogar noch schneller.
 
Rationaler und geringere Auslastung
Anders als seine Vorgänger ist Windows 7 darauf ausgelegt, verlangsamende Hintergrunddienste nur dann auszuführen, wenn Sie sie benötigen. Sie verwenden kein Bluetooth-Gerät? Dann bleibt der Bluetooth-Dienst von Windows 7 ausgeschaltet. Windows 7 benötigt auch weniger Arbeitsspeicher als Windows Vista: eine weitere versteckte Optimierung, mit der die Gesamtleistung gesteigert werden kann.
 
64-Bit-Unterstützung
Wenn Sie sich kürzlich nach einem neuen PC umgesehen haben, dann ist Ihnen sicherlich aufgefallen, dass es mehr Computer mit 64-Bit-Prozessoren gibt. Und möglicherweise haben Sie sich gefragt, welche Vorteile sie bieten. Einfach ausgedrückt, kann ein 64-Bit-PC größere Datenmengen verarbeiten als ein 32-Bit-System. Da mehr RAM (4 GB und mehr) verwendet werden kann, kann ein 64-Bit-Computer schneller reagieren, wenn Sie viele Programme gleichzeitig ausführen.
 
Welchen sollen Sie kaufen? Wenn Sie beabsichtigen, viele Programme gleichzeitig geöffnet zu haben oder häufig zwischen Programmen wechseln müssen und auch wenn Sie lediglich sicherstellen möchten, dass Ihr PC die derzeit größeren Speicher nutzen kann, dann ist ein 64-Bit-Computer die richtige Wahl für Sie. Wenn Sie hingegen höchstens zwei Programme gleichzeitig ausführen oder ältere Hardware und Software verwenden, die von einem 64-Bit-PC nicht unterstützt wird, ist ein 32-Bit-System geeignet. Egal, ob Sie sich für ein 32-Bit- oder ein 64-Bit-System entscheiden, Windows 7 ist bereit.
 
 
Die verbesserte Windows Suche liefert Ergebnisse mit mehr Relevanz 
 
Energieverwaltung
Sie haben es satt, dass sich der Akku Ihres Laptops immer dann verabschiedet, wenn Sie ihn dringend benötigen? Unter Windows 7 können Sie die Akkulaufzeit verlängern. Wie? Zunächst einmal ist die Anzahl von unter Windows 7 ausgeführten Hintergrundaktivitäten viel kleiner, d. h., der PC-Prozessor ist weniger stark ausgelastet und damit die Stromaufnahme geringer.
 
Zudem ist die DVD-Wiedergabe stromsparender (praktisch auf langen Flügen), der Bildschirm wird automatisch abgedunkelt, nicht verwendete Ports werden abgeschaltet, und die Anzeige für die Akkulaufzeit ist genauer. Es ist also unwahrscheinlicher, dass Sie plötzlich mit einem leeren Akku dastehen.
 
Windows 7 macht neue Dinge möglich
 
Netzwerk
Mit Windows 7 wird es zum Kinderspiel, auf dem Laptop an jedem beliebigen Ort Netzwerke anzuzeigen und eine Verbindung mit diesen herzustellen. Klicken Sie einfach nur auf das Netzwerksymbol auf der Taskleiste. Mit ""Verfügbare Netzwerke anzeigen"" werden alle Optionen für Drahtlos- und verkabelte Netzwerke aufgerufen: WiFi, mobiles Breitband, DFÜ oder Unternehmens-VPN. Nur noch ein Klick, und schon steht die Verbindung.
 
Windows Media Center
Live-TV anschauen, anhalten und aufnehmen. Musik hören. Mit der Fotosammlung Eindruck schinden. Onlineunterhaltung genießen. Und das vom Sofa im Wohnzimmer aus. Wundert es da noch, dass Media Center von Kritikern als das verborgene Juwel von Windows bezeichnet wird?
 
Unter Windows 7 wurde das Programm sogar noch erweitert: mit neuen, tollen Features (viele auf Ihre Anregung hin) und visuellen Verbesserungen. Windows Media Center ist in den Editionen Home Premium, Professional und Ultimate von Windows 7 enthalten. Zu den wichtigsten Neuerungen zählen u. a.:
 
 
Komponenten wie Dateien oder Drucker gemeinsam im Heimnetzwerk nutzen 
 
Fernsehen total ...
Windows Media Center unterstützt mehr globale TV-Standards und TV-Tuner (z. B. Digitalfernsehen und HD). Zudem können Sie mit dem Programm nun mehr häufig verwendete Audio- und Videoformate wiedergeben, z. B. 3GP, AAC, AVCHD, DivX, MOV und Xvid.
 
... ohne langes Warten
Haben Sie es satt, sich durch Fernsehprogramme oder eine umfangreiche Musikbibliothek zu quälen? Wechseln Sie schneller zu Titeln und Sendungen mit dem neuen Feature für schnelles Blättern.
 
Atemberaubende neue Diashows
Stellen Sie mit der neuen Diashowerstellung ansprechende Fotocollagen (mit Hintergrundmusik) zusammen. Die sind perfekt geeignet für Partys oder Familienfeiern. Und probieren Sie unbedingt den neuen Diashow-Bildschirmschoner aus: Dafür finden Sie keine Worte!
 
Einfachere Medienfreigabe
Schauen Sie sich aufgezeichnete TV-Sendungen, Musiktitel und Videos an, auch wenn diese nicht auf Ihrem PC gespeichert sind. Mit dem neuen Feature Heimnetzgruppe stehen Medien auf jedem PC unter Windows 7 im gesamten Haus zur Verfügung.
 
Neue Minianwendungen, größere Vorschau
Es gibt eine neue Media Center-Minianwendung. Videos im Schnelldurchlauf anschauen. Mehr Titel- und Sendungsdetails. Größere, besser erkennbare Vorschauminiaturansichten. Und das sind noch längst nicht alle Verbesserungen.
 
 
Windows BitLocker verschlüsselt komplette Laufwerke 
 
Windows Touch
Es hat sich ""ausgemaust"": Mit Windows 7 und einem Kontaktbildschirm können Sie einfach nur mit Ihren Fingern die Onlineausgabe der Tageszeitung durchsehen, die Seiten in einem Fotoalbum durchblättern und Dateien und Ordner zufällig anordnen.
 
Eine eingeschränkte Touchtechnologie ist bereits seit Jahren unter Windows verfügbar. Aber unter Windows 7 erobert sie jede Ecke Ihres PC. Das Startmenü und die Taskleiste weisen nun größere, fingerfreundliche Symbole auf. Auch die vertrauten Windows 7-Programme unterstützen die Fingereingabe. In Paint können Sie jetzt sogar mit dem Finger malen!
 
Windows Touch, nur in den Editionen Home Premium, Professional und Ultimate von Windows 7 enthalten, erkennt auch Mehrfingerbewegungen (geeigneten Monitor vorausgesetzt). Sie möchten ein Bild vergrößern? Bewegen Sie Ihre Finger aufeinander zu. Sie möchten einen Rechtsklick ausführen? Berühren Sie das entsprechende Element mit einem Finger, und tippen Sie mit einem anderen Finger auf den Bildschirm.
 
Zusätzliche Profi-Funktionen
 
Windows XP-Modus
Besser geht's nicht: Mit dem neuen Windows XP-Modus können Sie ältere Windows XP-Geschäftsprogramme direkt auf dem Windows 7-Desktop ausführen. Das Feature, das in erster Linie für kleine und mittelständische Unternehmen entwickelt wurde, steht als separater Download zur Verfügung und kann nur in Verbindung mit Windows 7 Professional und Ultimate eingesetzt werden. Der Windows XP-Modus setzt zudem auch eine Virtualisierungssoftware wie Windows Virtual PC voraus. Beides kann kostenlos von der Microsoft-Website heruntergeladen werden.
 
Domänenbeitritt
Nutzen Sie Ihren PC im Büro, oder planen Sie, ihn für die Heimarbeit zu verwenden? Dann müssen Sie ihn ggf. mit einer Domäne verbinden. Eine Domäne ist eine Art Computernetzwerk, das häufig am Arbeitsplatz vorgefunden wird. (Technisch gesehen, handelt es sich um eine Gruppe von Computern, die zentral verwaltet und unter Einhaltung allgemeiner Regeln betrieben wird.)
 
Windows 7 Professional und Ultimate ermöglichen einen schnellen und sicheren Domänenbeitritt. Führen Sie einfach den benutzerfreundlichen Assistenten aus, und geben Sie Ihre Anmeldeinformationen für das Netzwerk ein. Einen kurzen Moment später sind Sie schon drin.
 
BitLocker-Laufwerkverschlüsselung
Wie können Sie zum Schutz Ihrer Daten vor Datenverlust, Diebstahl oder Hackern beitragen? Die Antwort lautet: BitLocker. Das für Windows 7 verbesserte und in der Ultimate Edition verfügbare BitLocker-Feature hilft Ihnen, alles zu schützen, von Dokumenten bis hin zu Kennwörtern, indem das gesamte Laufwerk, auf dem sich Windows und Ihre Daten befinden, verschlüsselt wird. Sobald BitLocker aktiviert ist, wird jede auf dem Laufwerk gespeicherte Datei automatisch verschlüsselt. BitLocker To Go, ein neues Feature von Windows 7, ermöglicht die Sperrung von leicht verlegten tragbaren Speichergeräten wie USB-Flashlaufwerken und externen Festplatten.
 
Features:
 

Inklusive 32- und 64-Bit-Version
Handbuch: mit Installationsanleitung, Schnelleinstieg und Erklärung der wichtigsten Neuerungen von Windows 7.
Installationssupport: telefonischer Support ist enthalten.
Schneller und einfacher zu bedienen
Verbesserte Taskleiste und Vollbild-Vorschaufenster
Sprunglisten für schnellen Zugriff auf die Programme und Dateien
Verbesserter Desktop vereinfacht das Arbeiten mit Fenstern
Verbesserte Windows Suche
Bessere Geräteverwaltung
Automatisches Einrichten von Heimnetzgruppen
Verbesserte Energieverwaltung
Höchste Kompatibilität
Windows Media Center mit optimierter Benutzeroberfläche
Im ganzen Haus auf Musik, Fotos und Videos zugreifen
Immer auf dem neuesten Stand mit Windows Live
Windows Touch für berührungsempfindliche Bildschirme
Location Aware Printing
Domänenunterstützung und Gruppenrichtlinien
Remote Desktop Host
Erweiterte Datensicherung (Netzwerk und Gruppenrichtlinien)
Windows XP Mode
Verschlüsselndes Dateisystem (EFS)
BitLocker & BitLocker To Go
AppLocker
DirectAccess
BranchCache
Mehrsprachige Bedienerführung (MUI)
 
";2;False;0;;;Windows 7 32 Bit;windows-7-32-bit;True;True;P-2980;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;74.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40889,6296990741;"30;80";3;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000393-windows-7-32-bit.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000394-windows-7-32-bit.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000395-windows-7-32-bit.jpg;1;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Windows 7 64 Bit;Windows 7 64 Bit;"
Windows 7  
 
Die umfassendste Edition von Windows 7
Windows 7 Ultimate ist die vielseitigste und leistungsfähigste Edition von Windows 7. Sie kombiniert die bemerkenswerte Benutzerfreundlichkeit der Unterhaltungsfunktionen von Home Premium mit den unternehmensorientierten Funktionen von Professional, wozu auch die Fähigkeit zum Ausführen zahlreicher Windows XP-Produktivitätsprogramme im Windows XP-Modus gehört.
 
Für mehr Sicherheit können Sie Ihre Daten auch mit BitLocker und Bitlocker To Go verschlüsseln. Und zur Erhöhung der Flexibilität können Sie in einer beliebigen von 35 Sprachen arbeiten. Mit Windows 7 Ultimate müssen Sie auf nichts verzichten.
 
Windows 7 vereinfacht alltägliche Aufgaben
 
Desktop
Unter Windows 7 ist es nun einfacher, noch mehr Aufgaben direkt auf dem Desktop zu erledigen: Verbesserte Taskleistenvorschau, größere Symbole, Anheften und kreative Möglichkeiten der Personalisierung.
 
Neue Möglichkeiten, mit Fenstern zu jonglieren
Überwältigt von der Zahl der geöffneten Fenster? Windows 7 bietet drei einfache und dennoch leistungsfähige neue Funktionen, die wie folgt bezeichnet werden: Aero Shake, Aero Peek und Snap. Sie unterstützen Sie dabei, sofort den Weg durch den Desktop zu finden.
 
 
Die verschiedenen Windows 7 Editionen im Vergleich 
 
Spektakuläre neue Hintergrundbilder
Seien wir ehrlich: Wir verbringen jede Menge Zeit damit, auf unsere PCs zu starren. Die Ästhetik sollte daher nicht zu kurz kommen. Darum enthält Windows 7 viele neue Desktophintergründe, so genannte Hintergrundbilder, unter denen sich alle möglichen Motive von beeindruckend bis unterhaltsam befinden. Oder probieren Sie doch einmal die neue Desktopdiashow aus, in der eine wiederkehrende Reihe von Bildern (unserer oder Ihrer) angezeigt wird. Desktop und langweilig? Das ist vorbei.
 
Schauen Sie sich die "Superleiste" an
Schon unter Windows 95 hat die Taskleiste als Ausgangspunkt zum Starten von Programmen und Umschalten zwischen Fenstern gedient. Nicht nur die Zeiten, auch die Arbeitsweisen am PC haben sich geändert. Unter Windows 7 wurde die Taskleiste daher komplett neu gestaltet, damit Sie noch mehr Aufgaben erledigen können. Sie ist ansprechender, kann besser angepasst werden und vereinfacht das Multitasking.
 
Heimnetzgruppe
Dank der Heimnetzgruppe brauchen Sie sich keine Gedanken mehr über die Datei- und Druckerfreigabe in einem Heimnetzwerk zu machen. Verbinden Sie mindestens zwei Windows 7-PCs, und schon kann mit der Heimnetzgruppe ganz einfach die automatische Freigabe von Musik, Bildern, Videos und Dokumentbibliotheken für andere Personen im Haus starten. Und das neue Menü "Freigeben für" ermöglicht die schnelle Freigabe einzelner Dateien.
 
Machen Sie sich Sorgen um den Datenschutz? Wir auch. Und deshalb ist die Heimnetzgruppe kennwortgeschützt, sodass Sie die volle Kontrolle über den Zugriff haben. Sie entscheiden, welche Dateien freigegeben werden und welche nicht. Außerdem können Sie Ihre Dateien mit Schreibschutz versehen, d. h., der Inhalt kann von anderen angesehen, aber nicht geändert werden. Einer Heimnetzgruppe beizutreten, ist in jeder Edition von Windows 7 möglich. Das Erstellen einer Heimnetzgruppe ist jedoch nur in den Editionen Home Premium, Professional und Ultimate möglich.
 
 
Die verbesserte Taskleiste verschafft mit Hilfe der neuen Vollbild-Vorschaufenster schnellen Überblick 
 
Sprunglisten
Über die in Windows 7 neu eingeführten Sprunglisten gelangen Sie nun direkt zu den Dokumenten, Bildern, Songs oder Websites, die Sie tagtäglich nutzen. Zum Öffnen einer Sprungliste klicken Sie auf der Taskleiste von Windows 7 einfach mit der rechten Maustaste auf ein Programm (Sie sind auch im Startmenü zu finden.).
 
Der Inhalt einer Sprungliste hängt vom Programm ab. In der Sprungliste für Internet Explorer 8 werden häufig besuchte Websites angezeigt. Windows Media Player 12 enthält häufig abgespielte Musiktitel. Fehlt in der Sprungliste ein Favorit? Sie können dort beliebige Dateien "anheften". In Sprunglisten werden nicht nur Verknüpfungen zu Dateien angezeigt. Manchmal bieten sie auch Schnellzugriff auf Befehle für Aufgaben wie das Verfassen neuer E-Mail-Nachrichten oder das Wiedergeben von Musik.
 
Snap
Snap bietet eine schnelle neue Möglichkeit, die Größe geöffneter Fenster einfach durch Ziehen an die Bildschirmränder zu ändern. Je nach Rand, also, oben oder unten, rechts oder links, wird das Fenster verbreitert, oder es füllt den ganzen Bildschirm aus. Und Sie können Fenster auch nebeneinander anordnen. Mit Snap wird das Lesen, das Anordnen und das Vergleichen von Fenstern zum Kinderspiel.
 
 
Den Desktop jederzeit im Blick dank transparenter Fenster 
 
Windows Live Essentials
Was ist Windows Live Essentials? Einfach ausgedrückt, handelt es sich um kostenlose Software, die einen Windows 7-PC mit noch mehr tollen Funktionen ausstattet, z. B. für E-Mail, Instant Messaging, Fotobearbeitung und Blogs. Windows Live Windows Live Essentials ist auf der Windows Live-Website verfügbar. Der kostenlose Download enthält folgende Komponenten: Messenger, Fotogalerie, Mail, Writer, Movie Maker, Symbolleiste und Family Safety.
 
Windows Search
Unter Windows 7 finden Sie noch schneller noch mehr Dinge an noch mehr Orten. Sobald Sie im Suchfeld des Startmenüs mit der Eingabe beginnen, wird eine Liste relevanter Dokumente, Bilder, Musiktitel und E-Mails auf dem PC angezeigt. Die Ergebnisse sind nun nach Kategorie gruppiert und enthalten hervorgehobene Stichwörter und Textausschnitte, um die Suche zu vereinfachen.
 
Dateien werden heutzutage nur noch selten an einem Ort abgelegt. Also ist Windows 7 auch darauf ausgelegt, externe Festplatten, Netzwerk-PCs und Bibliotheken zu durchsuchen. Zu viele Suchergebnisse? Sie können die Suche direkt nach Datum, Dateityp und anderen hilfreichen Kategorien eingrenzen.
 
Windows 7 funktioniert Ihren Vorstellungen entsprechend
 
Leistungsverbesserungen
Niemand wartet gerne. Darum ist Windows 7 nun noch schneller und immer bereit, wenn Sie es sind. Zu den wichtigen Leistungsverbesserungen zählen u. a. schneller Wechsel in und aus dem Energiesparmodus, weniger Speicherbedarf und schnelle Erkennung von USB-Geräten:
 
Standbymodus
Windows 7 kann in den Energiesparmodus versetzt und wiederhergestellt werden und die Verbindung mit dem Drahtlosnetzwerk wieder schneller herstellen.
 
 
Sprunglisten ermöglichen schnellen Zugriff auf häufig anstehende Aufgaben 
 
Suchen
Wenn Sie auf der Suche nach Informationen sind, dann möchten Sie nicht lange warten, sondern Antworten bekommen. Unter Windows 7 werden Suchergebnisse schneller angezeigt. Auch das Sortieren und Gruppieren von Suchergebnissen geht viel rascher vonstatten.
 
USB-Geräte
Wenn Sie zum ersten Mal ein tragbares Flashlaufwerk oder ein anderes USB-Gerät anschließen, stellt Windows 7 es innerhalb weniger Sekunden für Sie bereit. Und wenn Sie es bereits zuvor verwendet haben, dann geht es sogar noch schneller.
 
Rationaler und geringere Auslastung
Anders als seine Vorgänger ist Windows 7 darauf ausgelegt, verlangsamende Hintergrunddienste nur dann auszuführen, wenn Sie sie benötigen. Sie verwenden kein Bluetooth-Gerät? Dann bleibt der Bluetooth-Dienst von Windows 7 ausgeschaltet. Windows 7 benötigt auch weniger Arbeitsspeicher als Windows Vista: eine weitere versteckte Optimierung, mit der die Gesamtleistung gesteigert werden kann.
 
64-Bit-Unterstützung
Wenn Sie sich kürzlich nach einem neuen PC umgesehen haben, dann ist Ihnen sicherlich aufgefallen, dass es mehr Computer mit 64-Bit-Prozessoren gibt. Und möglicherweise haben Sie sich gefragt, welche Vorteile sie bieten. Einfach ausgedrückt, kann ein 64-Bit-PC größere Datenmengen verarbeiten als ein 32-Bit-System. Da mehr RAM (4 GB und mehr) verwendet werden kann, kann ein 64-Bit-Computer schneller reagieren, wenn Sie viele Programme gleichzeitig ausführen.
 
Welchen sollen Sie kaufen? Wenn Sie beabsichtigen, viele Programme gleichzeitig geöffnet zu haben oder häufig zwischen Programmen wechseln müssen und auch wenn Sie lediglich sicherstellen möchten, dass Ihr PC die derzeit größeren Speicher nutzen kann, dann ist ein 64-Bit-Computer die richtige Wahl für Sie. Wenn Sie hingegen höchstens zwei Programme gleichzeitig ausführen oder ältere Hardware und Software verwenden, die von einem 64-Bit-PC nicht unterstützt wird, ist ein 32-Bit-System geeignet. Egal, ob Sie sich für ein 32-Bit- oder ein 64-Bit-System entscheiden, Windows 7 ist bereit.
 
 
Die verbesserte Windows Suche liefert Ergebnisse mit mehr Relevanz 
 
Energieverwaltung
Sie haben es satt, dass sich der Akku Ihres Laptops immer dann verabschiedet, wenn Sie ihn dringend benötigen? Unter Windows 7 können Sie die Akkulaufzeit verlängern. Wie? Zunächst einmal ist die Anzahl von unter Windows 7 ausgeführten Hintergrundaktivitäten viel kleiner, d. h., der PC-Prozessor ist weniger stark ausgelastet und damit die Stromaufnahme geringer.
 
Zudem ist die DVD-Wiedergabe stromsparender (praktisch auf langen Flügen), der Bildschirm wird automatisch abgedunkelt, nicht verwendete Ports werden abgeschaltet, und die Anzeige für die Akkulaufzeit ist genauer. Es ist also unwahrscheinlicher, dass Sie plötzlich mit einem leeren Akku dastehen.
 
Windows 7 macht neue Dinge möglich
 
Netzwerk
Mit Windows 7 wird es zum Kinderspiel, auf dem Laptop an jedem beliebigen Ort Netzwerke anzuzeigen und eine Verbindung mit diesen herzustellen. Klicken Sie einfach nur auf das Netzwerksymbol auf der Taskleiste. Mit "Verfügbare Netzwerke anzeigen" werden alle Optionen für Drahtlos- und verkabelte Netzwerke aufgerufen: WiFi, mobiles Breitband, DFÜ oder Unternehmens-VPN. Nur noch ein Klick, und schon steht die Verbindung.
 
Windows Media Center
Live-TV anschauen, anhalten und aufnehmen. Musik hören. Mit der Fotosammlung Eindruck schinden. Onlineunterhaltung genießen. Und das vom Sofa im Wohnzimmer aus. Wundert es da noch, dass Media Center von Kritikern als das verborgene Juwel von Windows bezeichnet wird?
 
Unter Windows 7 wurde das Programm sogar noch erweitert: mit neuen, tollen Features (viele auf Ihre Anregung hin) und visuellen Verbesserungen. Windows Media Center ist in den Editionen Home Premium, Professional und Ultimate von Windows 7 enthalten. Zu den wichtigsten Neuerungen zählen u. a.:
 
 
Komponenten wie Dateien oder Drucker gemeinsam im Heimnetzwerk nutzen 
 
Fernsehen total ...
Windows Media Center unterstützt mehr globale TV-Standards und TV-Tuner (z. B. Digitalfernsehen und HD). Zudem können Sie mit dem Programm nun mehr häufig verwendete Audio- und Videoformate wiedergeben, z. B. 3GP, AAC, AVCHD, DivX, MOV und Xvid.
 
... ohne langes Warten
Haben Sie es satt, sich durch Fernsehprogramme oder eine umfangreiche Musikbibliothek zu quälen? Wechseln Sie schneller zu Titeln und Sendungen mit dem neuen Feature für schnelles Blättern.
 
Atemberaubende neue Diashows
Stellen Sie mit der neuen Diashowerstellung ansprechende Fotocollagen (mit Hintergrundmusik) zusammen. Die sind perfekt geeignet für Partys oder Familienfeiern. Und probieren Sie unbedingt den neuen Diashow-Bildschirmschoner aus: Dafür finden Sie keine Worte!
 
Einfachere Medienfreigabe
Schauen Sie sich aufgezeichnete TV-Sendungen, Musiktitel und Videos an, auch wenn diese nicht auf Ihrem PC gespeichert sind. Mit dem neuen Feature Heimnetzgruppe stehen Medien auf jedem PC unter Windows 7 im gesamten Haus zur Verfügung.
 
Neue Minianwendungen, größere Vorschau
Es gibt eine neue Media Center-Minianwendung. Videos im Schnelldurchlauf anschauen. Mehr Titel- und Sendungsdetails. Größere, besser erkennbare Vorschauminiaturansichten. Und das sind noch längst nicht alle Verbesserungen.
 
 
Windows BitLocker verschlüsselt komplette Laufwerke 
 
Windows Touch
Es hat sich "ausgemaust": Mit Windows 7 und einem Kontaktbildschirm können Sie einfach nur mit Ihren Fingern die Onlineausgabe der Tageszeitung durchsehen, die Seiten in einem Fotoalbum durchblättern und Dateien und Ordner zufällig anordnen.
 
Eine eingeschränkte Touchtechnologie ist bereits seit Jahren unter Windows verfügbar. Aber unter Windows 7 erobert sie jede Ecke Ihres PC. Das Startmenü und die Taskleiste weisen nun größere, fingerfreundliche Symbole auf. Auch die vertrauten Windows 7-Programme unterstützen die Fingereingabe. In Paint können Sie jetzt sogar mit dem Finger malen!
 
Windows Touch, nur in den Editionen Home Premium, Professional und Ultimate von Windows 7 enthalten, erkennt auch Mehrfingerbewegungen (geeigneten Monitor vorausgesetzt). Sie möchten ein Bild vergrößern? Bewegen Sie Ihre Finger aufeinander zu. Sie möchten einen Rechtsklick ausführen? Berühren Sie das entsprechende Element mit einem Finger, und tippen Sie mit einem anderen Finger auf den Bildschirm.
 
Zusätzliche Profi-Funktionen
 
Windows XP-Modus
Besser geht's nicht: Mit dem neuen Windows XP-Modus können Sie ältere Windows XP-Geschäftsprogramme direkt auf dem Windows 7-Desktop ausführen. Das Feature, das in erster Linie für kleine und mittelständische Unternehmen entwickelt wurde, steht als separater Download zur Verfügung und kann nur in Verbindung mit Windows 7 Professional und Ultimate eingesetzt werden. Der Windows XP-Modus setzt zudem auch eine Virtualisierungssoftware wie Windows Virtual PC voraus. Beides kann kostenlos von der Microsoft-Website heruntergeladen werden.
 
Domänenbeitritt
Nutzen Sie Ihren PC im Büro, oder planen Sie, ihn für die Heimarbeit zu verwenden? Dann müssen Sie ihn ggf. mit einer Domäne verbinden. Eine Domäne ist eine Art Computernetzwerk, das häufig am Arbeitsplatz vorgefunden wird. (Technisch gesehen, handelt es sich um eine Gruppe von Computern, die zentral verwaltet und unter Einhaltung allgemeiner Regeln betrieben wird.)
 
Windows 7 Professional und Ultimate ermöglichen einen schnellen und sicheren Domänenbeitritt. Führen Sie einfach den benutzerfreundlichen Assistenten aus, und geben Sie Ihre Anmeldeinformationen für das Netzwerk ein. Einen kurzen Moment später sind Sie schon drin.
 
BitLocker-Laufwerkverschlüsselung
Wie können Sie zum Schutz Ihrer Daten vor Datenverlust, Diebstahl oder Hackern beitragen? Die Antwort lautet: BitLocker. Das für Windows 7 verbesserte und in der Ultimate Edition verfügbare BitLocker-Feature hilft Ihnen, alles zu schützen, von Dokumenten bis hin zu Kennwörtern, indem das gesamte Laufwerk, auf dem sich Windows und Ihre Daten befinden, verschlüsselt wird. Sobald BitLocker aktiviert ist, wird jede auf dem Laufwerk gespeicherte Datei automatisch verschlüsselt. BitLocker To Go, ein neues Feature von Windows 7, ermöglicht die Sperrung von leicht verlegten tragbaren Speichergeräten wie USB-Flashlaufwerken und externen Festplatten.
 
Features:
 

Inklusive 32- und 64-Bit-Version
Handbuch: mit Installationsanleitung, Schnelleinstieg und Erklärung der wichtigsten Neuerungen von Windows 7.
Installationssupport: telefonischer Support ist enthalten.
Schneller und einfacher zu bedienen
Verbesserte Taskleiste und Vollbild-Vorschaufenster
Sprunglisten für schnellen Zugriff auf die Programme und Dateien
Verbesserter Desktop vereinfacht das Arbeiten mit Fenstern
Verbesserte Windows Suche
Bessere Geräteverwaltung
Automatisches Einrichten von Heimnetzgruppen
Verbesserte Energieverwaltung
Höchste Kompatibilität
Windows Media Center mit optimierter Benutzeroberfläche
Im ganzen Haus auf Musik, Fotos und Videos zugreifen
Immer auf dem neuesten Stand mit Windows Live
Windows Touch für berührungsempfindliche Bildschirme
Location Aware Printing
Domänenunterstützung und Gruppenrichtlinien
Remote Desktop Host
Erweiterte Datensicherung (Netzwerk und Gruppenrichtlinien)
Windows XP Mode
Verschlüsselndes Dateisystem (EFS)
BitLocker & BitLocker To Go
AppLocker
DirectAccess
BranchCache
Mehrsprachige Bedienerführung (MUI)
";2;False;0;;;Windows 7 64 Bit;windows-7-64-bit;True;True;P-2990;;;False;0;False;;False;False;0;False;0;1;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;59.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40889,6295138889;"30;80";3;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000393-windows-7-32-bit.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000397-windows-7-32-bit.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000396-windows-7-32-bit.jpg;2;;False;ounce;;;;False;False;False;;;;;False;;;;;; +5;0;True;Toshiba Satellite L775-11K 43,9 cm (17,3 Zoll) Notebook;4 GB, 18 Zoll, 300 GB, Intel, 2;"
Der Satellite L775 bietet Ihnen die perfekte Mischung aus schickem Design und starker Leistung. Hier bekommen Sie nicht nur eine umfangreiche Ausstattung, sondern auch echte High-Definition-Performance. Intel®-Prozessoren der zweiten Generation sorgen für zügiges Arbeiten in all Ihren Anwendungen. Das 43,9 cm (17,3"") TruBrite® HD+ Display mit LED-Hintergrundbeleuchtung liefert in Kombination mit der NVIDIA® ein umwerfendes Bild. Dolby® AdvancedAudio-Technologie und integrierte Onkyo®-Lautsprecher mit guter Klangqualität runden die Multimedia-Ausstattung ab. Dazu noch ein Multitouch-Touchpad, 2und ein attraktives Matrix-Design in der Farbvariante Zinkgrau – bei diesem Notebook bleiben wirklich keine Wünsche offen.
 
Attraktives Design
Modernes Hochglanzgehäuse mit Matrix-Finish in Zinkgrau.
 
Beste Bildqualität
Das riesige 43,9 cm (17,3"") TruBrite® HD+ Display mit LED-Hintergrundbeleuchtung bietet beste High-Definition-Qualität. Eine hoch auflösende Bildwiedergabe wird dadurch selbst bei DVDs möglich.
 
Optimaler Klang
Integrierte Onkyo®-Lautsprecher sorgen in Kombination mit der Dolby® Advanced Audio-Technologie für einen vollen Sound.
 
Ultra schnell
USB 3.0-Technologie ermöglicht für ihre Multimedia-Dateien einen schnelleren Datentransfers als je zuvor.
 
""USB Sleep-and-Charge""-Funktion
Sie können Ihr Handy oder MP3 Player aufladen – und zwar selbst, wenn das Notebook ausgeschaltet ist.
 
Bedienerfreundlich
Touchpad mit Multitouch Gestensteuerung, Touch Pad an/aus Taste, Multi-Kartenleser und Tastatur mit 10er Nummernblock.
 
Entertainment
Kinoerlebnis auf einem externen Fernseher genießen über RGB (VGA) Anschluss oder in High Definition Qualität mit HDMI Anschluss.
 
Umweltfreundlich
Eco Stromsparfunktion, ENERGY STAR 5.0 qualifiziert und ein energieeffizientes Display mit LED Hintergrundbeleuchtung. 
";2;False;0;;;Toshiba Satellite L775-11K 43,9 cm (17,3 Zoll) Notebook;toshiba-satellite-l775-11k-439-cm-173-zoll-notebook;True;True;P-0840;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;539.9000;539.9000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40889,5852777778;5;40;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000590-toshiba-satellite-l775-11k-439-cm-173-zoll-notebook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000591-toshiba-satellite-l775-11k-439-cm-173-zoll-notebook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000592-toshiba-satellite-l775-11k-439-cm-173-zoll-notebook.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Logitech HD Webcam C615 ";"Logitech HD Webcam C615 ";"
Logitech HD Webcam C615
Mit dieser flexibel zusammenklappbaren Webcam führen Sie HD-Videogespräche in 720p und laden Full HD-Videos in 1080p mit nur einem Klick auf Facebook hoch. Inhalte, Ort und Setup wählen Sie.
 
Full HD-Videoaufnahmen in 1080p und HD-Videogespräche in 720p
Zeichnen Sie Ihr Videos in Full HD 1080p und im atemberaubenden Breitbildformat auf. Sie können Videogespräche in 720p mit den meisten Instant Messengern und Logitech Vid™ HD führen.* Dank des eingebauten Autofokus bleiben Ihre Bilder selbst bei Nahaufnahmen (ab einer Entfernung von 10 cm vom Objektiv) gestochen scharf. Machen Sie hochauflösende Schnappschüsse mit bis zu 8 Megapixeln (Software-interpoliert).
 

1-Klick-Upload auf Facebook
Mit nur einem Klick können Sie Full HD-Videoaufnahmen in 1080p-Auflösung erfassen und auf Facebook, Twitter™ oder YouTube® hochladen.
 

Flexibles, tragbares Design
Dank des zusammenklappbaren Designs und des kurzen USB-Kabels ist die Webcam leicht zu transportieren. Das USB-Verlängerungskabel bietet Ihnen bei Bedarf zusätzlichen Spielraum.
 
Drehbares Design mit Stativhalterung
Wenn Sie die Webcam an einem Stativ befestigen, haben Sie noch mehr Stellmöglichkeiten. Dank der 360-Grad-Schwenkfunktion sind Gespräche und Aufnahmen aus jedem Winkel möglich. Das Stativ selbst ist nicht im Lieferumfang enthalten.
 
Kompatibel mit Windows und Mac
Windows? Mac? iChat®? Skype™? Google Voice™ und Chat? Ganz egal. Ihre Webcam funktioniert mit allen. Für die Bearbeitung Ihrer Fotos ist sie außerdem mit iPhoto®, iMovie® und sogar mit Photo Booth® kompatibel.
 

Beinhaltet Logitech Vid™ HD
Jetzt sind HD-Videogespräche kostenlos, schnell und einfach. Die Software wird bei der Einrichtung Ihrer Webcam mitinstalliert. Und Sie können sogar Videonachrichten für Freunde und Familie hinterlassen, wenn diese Ihren Anruf nicht entgegennehmen können.
 
Kostenlose Videobearbeitungssoftware
Logitech und MAGIX machen Ihnen ein besonderes Angebot: Sie erhalten jetzt mit Ihrer neuen Logitech-Webcam auch gleich MAGIX™ Photo Manager 9 und MAGIX™ Video Easy. Und zwar kostenlos.****
 
Anmeldung über Gesichtserkennung
Melden Sie sich bei Ihrem Computer und auf Ihren Lieblings-Internetseiten mit der eingebauten Gesichtserkennungssoftware an. Damit sparen Sie Zeit und imponieren Ihren Freunden.*****
 

* Für Mac® sind HD-Videogespräche mit Logitech Vid™ HD verfügbar. Für HD-Videogespräche mit anderer Software überprüfen Sie bitte die Verfügbarkeit.
** Nicht für Mac verfügbar.
*** Nur für Windows-Computer. Intel® Pentium® 4 (2,8 GHz) empfohlen.
**** E-Mail-Registrierung erforderlich. Es gelten zusätzliche Bestimmungen. Nur für Windows-Computer.
***** 60-Tage-Probeangebot. Es gelten zusätzliche Bestimmungen. Nicht für Mac verfügbar.
";2;False;0;;;"Logitech HD Webcam C615 ";logitech-hd-webcam-c615;True;True;P-2910;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;89.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40889,4833449074;27;11;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000240-logitech-hd-webcam-c615.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000241-logitech-hd-webcam-c615.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000242-logitech-hd-webcam-c615.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Microsoft Wired LifeCam VX-3000 ";"Microsoft Wired LifeCam VX-3000 ";"
LifeCam VX-3000
 
Die LifeCam VX-3000 begeistert mit leichter Installation und nahtloser Integration in den Windows Live-Messenger. Die kompakte Webcam bietet Top-Bildqualität, kombiniert mit innovativen Features wie der praktischen Windows Live Call-Taste und dem multifunktionalem Standfuß, der sich mit einem Handgriff in eine Halterung für Flachbildschirme verwandeln lässt. Dank integriertem Mikrofon muss kein externes Mikrofon für unterhaltsame Video-Gespräche angeschlossen werden.
 
  Hochauflösende Fotos
Mit hochauflösenden Fotos (1,3 Megapixel interpoliert) zeigen Sie sich von Ihrer besten Seite.
 
Integriertes Mikrofon
Das integrierte Mikrofon erfasst Ihre Stimme automatisch und mit außergewöhnlicher Klarheit.
 
Windows Live Call-Taste
Um einen Videoanruf zu starten, drücken Sie einfach diese Taste, und wählen Sie dann einen Onlinekontakt aus.
 
Software für automatisches Face-Tracking*
Sie können sich bewegen, ohne vom Bildschirm zu verschwinden. Dank modernster Software bleibt Ihr Gesicht stets im Bildmittelpunkt.
 
 
Universalhalterung
Die LifeCam lässt sich problemlos an jedem Monitor befestigen.
 
Kipp-, Dreh- und Zoomfunktion
Die Kamera kann sowohl horizontal als auch vertikal geschwenkt werden und bietet somit ein Höchstmaß an Flexibilität.
 
Flexibles 1,8 m langes Kabel
Das lange, flexible Kabel gibt Ihnen genügend Bewegungsfreiheit.
 
Videoeffekte
Überraschen Sie Ihre Freunde mit coolen Videoeffekten, auf die Sie direkt aus dem Windows Live Messenger-Fenster zugreifen können.
 
Bis zu 30 Bilder pro Sekunde
Die Aufnahmen mit LifeCams erfolgen mit 30 Bildern pro Sekunde, wodurch die Videobilder flüssig und ohne Ruckeln angezeigt werden
 
 
 
 
 
";2;False;0;;;"Microsoft Wired LifeCam VX-3000 ";microsoft-wired-lifecam-vx-3000;True;True;P-2900;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;29.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40889,480775463;27;3;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000237-microsoft-wired-lifecam-vx-3000.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000238-microsoft-wired-lifecam-vx-3000.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000239-microsoft-wired-lifecam-vx-3000.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;SanDisk Secure Dügital Speicherkarte;"SanDisk Secure Digital (SD) Speicherkarte ";"
SanDisk Secure Digital (SD) Speicherkarte 
SecureDigital High Capacity Card (SDHC), entspricht neuem SD-2.0-Standard, Klasse 4
nur geeignet für Endgeräte mit SDHC-Steckplatz (nicht rückwärtskompatibel zu Standard-SD-Cards)
Schutz gegen unbeabsichtigtes Überschreiben der Daten
beliebig oft beschreib- und löschbar
original SanDisk Markenware, Erstausrüsterqualität
";2;False;0;;;SanDisk Secure Digital Speicherkarte;sandisk-secure-duegital-speicherkarte;True;True;P-2890;;;False;0;False;;False;False;0;False;0;1;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;1;9589;False;False;0;1;1;0;False;1;10000;;False;False;False;False;9.8000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40889,4440046296;25;;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000125-sandisk-secure-dugital-speicherkarte.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000126-sandisk-secure-dugital-speicherkarte.jpg;;1;;False;ounce;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Samsung SE-S084D externer DVD Brenner (DVD±RW (±R DL) weiß ";"Samsung SE-S084D externer DVD Brenner (DVD±RW (±R DL) weiß ";"
Samsung SE-S084D – Exklusiver mobiler Brenner mit AV-Funktion.
Der mobile Brenner SE-S084D überzeugt durch Innovation, Funktion und Design. Er setzt neue Maßstäbe und hebt sich in seiner Verarbeitung und den Einsatzmöglichkeiten deutlich von aktuellen Modellen ab.Das hochwertige Finish mit Soft-Touch-Taste und trendiger metallischer Linie machen den schlanken Brenner von Samsung optisch zu einem Highlight. Die Qualität des Produktes gewährt hohe Mobilität und vermittelt allein durch die robuste Haptik Zuverlässigkeit.
 
Angeschlossen wird der Slim-Brenner SE-S084D via HiSpeed-USB. Ein zusätzliches Netzteil ist nicht notwendig, denn der Multiformatbrenner erreicht seine maximale Brenn- und Lesegeschwindigkeit über die Stromversorgung via USB BUS Power. Der 8fach Brenner ist kompatibel sowohl zu Windows als auch zu MAC Betriebssystemen; diese Kompatibilität wurde auch von beiden Partnern offiziell bestätigt. Somit ist seine grundsätzliche Funktion des Brennens und Lesen von Medien aller Art bestens sichergestellt.
 
Durch die leichte und kompakte Bauweise mit nur 270 Gramm ist er die perfekte Begleitung für Netbook, Notebook oder All-In-One PC.
 
Als zusätzliches Feature hat Samsung die AV-Funktion entwickelt. Unterstützt Ihr Fernseher die Wiedergabe via USB-Port. so lässt sich der SE-S084D an diese neue TV-Generation mit PVR Funktion anschließen und zum Abspielen JPEG, MP3 und AVI-Dateien nutzen. Der SE-S084D kann also auch als Player eingesetzt.
 
Dieses neue Produktkonzept wurde auch mit dem IF Design Award 2010 honoriert.
";2;False;0;;;"Samsung SE-S084D externer DVD Brenner (DVD±RW (±R DL) weiß ";samsung-se-s084d-externer-dvd-brenner-dvdrw-r-dl-weiss;True;True;P-2870;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;69.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40889,4407638889;24;19;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000287-samsung-se-s084d-externer-dvd-brenner-dvdrw-r-dl-weis.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000288-samsung-se-s084d-externer-dvd-brenner-dvdrw-r-dl-weis.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000289-samsung-se-s084d-externer-dvd-brenner-dvdrw-r-dl-weis.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Slim USB DVD CD Blu Ray Laufwerk Gehäuse Case extern IDE / PATA Schwarz ";"Slim USB DVD CD Blu Ray Laufwerk Gehäuse Case extern IDE / PATA Schwarz ";"
Externes USB-Gehäuse für optische Slim Blu-Ray, DVD und CD Laufwerke sowie Brenner
 
verwandelt Ihr internes Laufwerk in ein externes
 
- Hochwertiges Firstcom Gehäuse in Matt-Schwarz
- Unterstützt USB 1.1, USB 2.0 sowie USB 3.0
- Easy to Install / Sehr leichter Einbau
- Automatische Erkennung / Plug & Play bei Windows Me / 2000 / XP / Vista / Windows 7
Mac ab OS 8.6 oder höher (keine Treiber Installation notwendig)
- Stromversorgung über USB (Bus-powered / kein extra Netzteil nötig)
- Gummifüße verhindern ein Rutschen auf der Arbeitsfläche
- Abmessungen: 137 x 135 x 18 (L x B x H mm)
- für Slimline Laufwerke mit ca. 12,7 mm Höhe und IDE Anschluss geeignet
 
Lieferumfang:
1 x externes Slim Gehäuse
1 x USB <-> IDE Board (Schnittstelle zum Laufwerk)
1 x USB-Kabel für die Verbindung
1 x USB-Kabel für die Stromzufuhr
1 x Kurzanleitung
und diverses Einbaumaterial
 
Farbe: Schwarz
 
Kann auch am PC, MAC, Notebook, Sub Notebook, Netbook etc. verwendet werden.
Anmerkung: Ein Laufwerk ist nicht eingebaut und gehört nicht zum Lieferumfang.
";2;False;0;;;"Slim USB DVD CD Blu Ray Laufwerk Gehäuse Case extern IDE / PATA Schwarz ";slim-usb-dvd-cd-blu-ray-laufwerk-gehaeuse-case-extern-ide-pata-schwarz;True;True;P-2840;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;24.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40889,4399305556;24;;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000223-slim-usb-dvd-cd-blu-ray-laufwerk-gehause-case-extern-ide-pata-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000224-slim-usb-dvd-cd-blu-ray-laufwerk-gehause-case-extern-ide-pata-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000225-slim-usb-dvd-cd-blu-ray-laufwerk-gehause-case-extern-ide-pata-schwarz.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Samsung SE-406AB/RSBD extern Slim BluRay Combo Laufwerk;"Samsung SE-406AB/RSBD extern Slim BluRay Combo Laufwerk (CyberLink TrueTheater, 3D Support, USB 2.0) ";"
Erleben Sie HD-Kinospaß mit dem externen Slim Blu-ray Combo-Laufwerk SE-406AB für Ihr Notebook oder PC.
Mit dem neuen Samsung Blu-ray Combo-Laufwerk verbinden Sie Arbeit und Vergnügen perfekt miteinander. Klassisch können Sie mit dem portablen Laufwerk, CDs und DVDs in hoher Qualität lesen und beschreiben. Aber ebenso können Sie mit dem SE-406AB HD-Inhalte am eigenen PC abspielen oder selbst erstellte Inhalte auf DVD oder BD auch an einem Fernseher mit Smart-TV-Funktion ansehen. Der Anschluss geschieht komfortabel über USB.
 
Mit dem schlanken Design fällt das Laufwerk kaum ins Gewicht und lässt sich leicht transportieren. Dank Anschluss über USB benötigt es kein zusätzliches Netzteil und verbraucht nur wenig Energie. Das Samsung BD Combo ist extrem leise im Betrieb und zeichnet sich durch eine hohe Kompatibilität und überzeugende Brennergebnisse aus. Die unterstützte Buffer Under Run-Technologie verhindert Pufferunterlauffehler und ermöglicht das Beschreiben von Medien mit hoher Brenngeschwindigkeit.
 
Mit der beiliegenden Software CyberLink BluRay Disc Suite 7 lässt sich das Combo-Laufwerk bequem bedienen. Sie können mit dem Laufwerk und einem 3D-fähigen Display Ihre 2D-DVD-Filmsammlung jetzt auch in 3D erleben. Denn die Software kann 2D-Filme in plastische 3D-Bilder umwandeln. Möglich wird dies mit der CyberLink TrueTheater 3D-Software. Voraussetzung dafür ist natürlich, dass der Nutzer ein 3D-fähiges Anzeigegerät samt 3D-Brille besitzt.
 
Durch das Feature der AV-Konnektivität lässt sich das Gerät an Fernseher mit Smart TV-Funktion anschließen. Smart TV führt Online- und Offline-Inhalte auf dem Fernseher zu einem ganzheitlichen Erlebnis zusammen. So lassen sich gestreamte Medieninhalte in den Formaten JPEG, MP3 und AVI auf dem TV Gerät mit SMART Funktion wiedergeben. Das Laufwerk wird dazu einfach an die USB-Schnittstelle des Fernsehers angeschlossen und fungiert dabei wie ein USB-Stick. Dies ermöglicht das Auslesen der Inhalte auf dem Datenträger. Durch die Verbindung per USB-Anschluss ist der schnelle Zugriff auf Videos, Musik und Fotos gewährleistet.
 
Ein Beispiel für die Multifunktionalität des schicken Laufwerks:
Für Oma schnell eine Foto-DVD brennen, auf dem Notebook eine neue Software aufspielen und selbstgedrehte BD-Filme bearbeiten und anschließend auf dem Fernseher ansehen? Das Samsung Blu-ray Combo-Laufwerk SE-406AB erfüllt Ihnen all diese Wünsche.
";2;False;0;;;LSamsung SE-406AB/RSBD extern Slim BluRay Combo Laufwerk;samsung-se-406abrsbd-extern-slim-bluray-combo-laufwerk;True;True;P-2850;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;79.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40889,4370833333;24;;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000226-samsung-se-406abrsbd-extern-slim-bluray-combo-laufwerk.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000227-samsung-se-406abrsbd-extern-slim-bluray-combo-laufwerk.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000228-samsung-se-406abrsbd-extern-slim-bluray-combo-laufwerk.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Canon Pixma MP 630 Multifunktionsgerät;"Canon Pixma MP 630 Multifunktionsgerät ";"
Canon PIXMA MP620

Hochwertiges Multifunktionssystem mit 9.600-dpi*-Drucksystem und nur 1 Picoliter feinen Tintentröpfchen für Fotos und Dokumente in überragender Druckqualität. Erweiterte Funktionen zum Druckmedien-Handling für die Digitalfotografie, kreative Arbeiten und anspruchsvolle Privatanwender. Features
Drucken, Kopieren und Scannen
Brillante Fotoprints mit 9.600 x 2.400 dpi und 1 Picoliter feinen Tintentröpfchen*
Randlose Fotos im Format 10 x 15 cm in ca. 20 Sekunden*
5-Tintensystem
6,2 cm großes TFT-Farbdisplay mit Easy-Scroll-Bedienrad
Scanner mit 4.800 dpi
Direktscan auf Speicherkarte oder USB-Stick
CD/DVD–Druck
Automatische Duplexfunktion
 
Foto- und Dokumentdruck
Das hochwertige 9.600-dpi*-Drucksystem des PIXMA MP630 mit FINE-Druckkopf für bis zu 1 Picoliter feine Tintentröpfchen liefert beeindruckende Fotoprints. Der Druck eines randlosen Fotos im Format 10 x 15 cm erfolgt in ca. 20 Sekunden*.Die 1 Picoliter feinen Tintentröpfchen der neuen farbstoffbasierten Tinten – inkl. Fotoschwarz – erzeugen kontrastreiche Prints mit sanften Farbabstufungen und brillanten Details.
 
ChromaLife100+** ist ein System aus dem FINE-Druckkopf des PIXMA MP630, Canon Originaltinten und ausgewähltem original Canon Fotopapier. Diese drei einzigartigen Komponenten erzeugen brillante Fotoprints mit hoher Farbstabilität. Textdokumente können in Schwarzweiß oder Farbe gedruckt werden, wobei eine schwarze Pigmenttinte für gestochen scharfen Text sorgt.
 
Single-Ink-Technologie
5 Tintentanks sorgen für Qualität und Effizienz – ist eine Tinte aufgebraucht, muss nur der betreffende Tank ausgetauscht werden.
 
Bedienungsfreundlichkeit
Mit dem hoch auflösenden 6,2 cm großen TFT-Farbdisplay können Sie Ihre Fotos auch ohne Computer bequem ansehen und mit dem Easy-Scroll-Bedienrad durchsuchen, auswählen, bearbeiten und den Druckvorgang starten. Ebenso ist es möglich, Aufnahmen direkt von kompatiblen Speicherkarten, PictBridge-kompatiblen Digitalkameras oder -Camcordern auszudrucken. Mit der Quick-Start-Funktion stehen alle Optionen in wenigen Sekunden zur Verfügung.
 
Fortschrittliches Medien-Handling
Gestalten Sie individuelle bedruckbare CDs und DVDs, indem Sie mit der Software CD-LabelPrint Layouts mit Ihren Texten und Bildern erstellen. Die integrierte Duplexeinheit ermöglicht den automatischen beidseitigen Druck auf Normalpapier, was Papier spart. Zwei Papierzuführungen ermöglichen das gleichzeitige Bestücken des Druckers z. B. mit Normalpapier und Fotopapier.
 
Scannen
Dank der optischen Auflösung von 4.800 dpi sind hervorragende Farbscans möglich, die Sie direkt an den PC oder als E-Mail senden bzw. als PDF erstellen können. Die intuitive Software MP Navigator EX gewährleistet eine einfache Bedienung. Der Auto-Scan-Modus beschleunigt den Scanvorgang, indem der Vorlagentyp erkannt und die entsprechenden Einstellungen automatisch gewählt werden. Mit der praktischen Option zum Direktscan auf Speicherkarte oder USB-Stick können die gescannten Daten einfach und flexibel gespeichert und transportiert werden.
 
Betriebssysteme
Kompatibel mit Windows und Mac OS X
";2;False;0;;;Canon Pixma MP 630 Multifunktionsgerät;canon-pixma-mp-630-multifunktionsgeraet;True;True;P-2180;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;169.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40889,4313888889;"22;2095";25;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000133-canon-pixma-mp-630-multifunktionsgerat.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000134-canon-pixma-mp-630-multifunktionsgerat.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000135-canon-pixma-mp-630-multifunktionsgerat.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Apple iPhone 4S schwarz ";"Apple iPhone 4S schwarz ";"
Das neue iPhone 4S - jetzt mit Dual Core A5 Chip, neuer 8 MegaPixel-Kamera, iOS 5 und iCloud sowie dem neuen Siri.
 
Dual-Core A5 Chip. Der leistungsstärkste iPhone Prozessor aller Zeiten.
Mit zwei Prozessorkernen liefert der A5 Chip bis zu 2x mehr Leistung und bis zu 7x schnellere Grafik. Das wirst du merken. Und zwar schnell. Das iPhone 4S reagiert extrem schnell, was du sofort merkst, wenn du Apps öffnest, im Web surfst, beim Spielen und auch bei allem anderen. Und ganz egal was du machst, du kannst es richtig lange machen. Denn der A5 Chip ist so effizient, dass das iPhone 4S eine enorm lange Batterielaufzeit hat.
 
Die Kaum-zu-glauben-dass-es-ein-Handy-ist Kamera.
Wahrscheinlich die beste Kamera, die es je auf einem Telefon gab. Und dank fortschrittlichster Optik ist sie wahrscheinlich auch die einzige Kamera, die du brauchst. Schließlich hat sie eine Auflösung von 8 Megapixeln und eine spezielle Linse mit einer größeren f/2,4 Blende. Außerdem bietet sie einen optimierten rückwärtig belichteten Sensor, exzellenten Weißabgleich, verbesserte Farbgenauigkeit, Gesichtserkennung und reduzierte Bewegungsunschärfe. Es ist also ganz egal, wie viele Leute, wie viel Licht und wie viel Action du aufnimmst – alles sieht genau so aus, wie es aussehen soll. Und warte erst, bis du die Fotos siehst.
 
Siri. Dein intelligenter, hilfsbereiter Assistent.Du musst ihn nur fragen.
Jetzt kannst du dein iPhone einfach mit deiner Stimme benutzen. Sprich mit Siri so, wie du mit einer Person sprichst und sag ""Erinnere mich daran, Mama anzurufen, wenn ich zu Hause bin"" oder ""Brauche ich einen Schirm?"". Siri spricht Deutsch und versteht nicht nur, was du sagst, sondern auch was du meinst. Es erkennt, welche Apps für die richtige Antwort nötig sind. Und antwortet dir dann – wie dein persönlicher Assistent. Siri telefoniert, sendet Nachrichten, plant Meetings, legt Erinnerungen fest und mehr. Was noch? Frag einfach, und Siri sagt es dir selbst.
 
Videoaufnahmen. In fantastischem 1080p HD.
Nimm fantastische 1080p HD Videos auf, wo immer du bist. Durch die neue fortschrittliche Optik der Kamera ist das Licht immer genau richtig, die Farben immer leuchtend und alles sieht noch besser aus, als du es in Erinnerung hattest. Die Bildstabilisierung gleicht verwackelte Aufnahmen aus. Und du kannst Videos direkt auf dem iPhone bearbeiten und so schnell mit anderen teilen, wie du sie aufnimmst.
 
iOS. Das fortschrittlichste mobile Betriebssystem der Welt. Und auch das einfachste.
Jede neue iOS Version bietet Möglichkeiten, die alles noch einfacher machen. Deshalb ist iOS allen anderen um Jahre voraus. Und iOS 5 geht wieder einen großen Schritt weiter und bringt mehr als 200 neue Features auf das iPhone 4S. Hier sind nur einige unserer Favoriten.
 
iCloud. Deine Inhalte. Auf all deinen Geräten.
Mit iCloud kannst du deine Inhalte ganz einfach verwalten, denn iCloud erledigt alles für dich. iCloud speichert deine Musik, Fotos, Apps, Mails, Kontakte, Kalender, Dokumente und mehr und pusht alles drahtlos an all deine Geräte. Automatisch, nahtlos und einfach so.
 
Retina Display.Das ist ganz klar.
Auf dem iPhone 4S siehst du einfach alles gestochen scharf und lebendig. Das Retina Display ist das höchstauflösende Telefondisplay aller Zeiten. Die Pixeldichte ist so hoch, dass das menschliche Auge keine einzelnen Pixel erkennen kann. Was du aber ganz bestimmt siehst, sind gestochen scharfe Texte, Grafiken und Bilder. Alles sieht sogar noch besser aus als gedruckt.
 
FaceTime. Wink doch mal hallo.
Mit FaceTime hörst du nicht nur eine Stimme, sondern siehst auch das Gesicht dazu – von iPhone zu iPhone, iPad 2, iPod touch oder Mac über Wi-Fi. Es ist also ganz egal, wo die anderen sind und wo du bist – du bist immer da. FaceTime Anrufe sind so einfach wie ganz normale Anrufe. Und mit Siri sind sie sogar noch einfacher. Sag Siri einfach, dass du mit deiner Mutter facetimen willst, und schon seht ihr euch. Einfach so. Du verpasst nie wieder ein wichtiges Ereignis, Meeting oder einen guten Lacher. Und wer würde sich nicht darüber freuen, dich zu sehen?
 
AirPlay. Live vom iPhone auf deinen Fernseher.
Mit AirPlay kannst du Inhalte von deinem iPhone via Apple TV drahtlos an deinen HD Fernseher und Lautsprecher streamen.6 Und mit der AirPlay Synchronisierung erscheint alles, was du auf deinem iPhone siehst oder machst, gleichzeitig auf deinem HD Fernseher.
 
AirPrint.Alles drahtlos drucken.
Drucke deine Mails, Fotos, Webseiten und Dokumente einfach über Wi-Fi von deinem iPhone aus.7 Ganz ohne Software zu laden, Treiber zu installieren oder Kabel anzuschließen. Nur ein paar Fingertipps und schon hast du das, was eben noch auf dem iPhone war, als Ausdruck in der Hand.
 
Besser. Schneller. Weltweiter.
Das iPhone 4S ist das erste Telefon, das zum Übertragen und Empfangen intelligent zwischen zwei Antennen wechselt. So ist die Anrufqualität deutlich besser. Außerdem verdoppeln die Antennen die maximale HSDPA Datengeschwindigkeit auf 14,4 Mbit/s.8 Und das bedeutet schnellere Verbindungen, schnelleres Laden und Neuladen und schnellere Downloads. Das iPhone 4S ist ein Telefon für die ganze Welt. Du kannst es also fast überall verwenden. Ob GSM- oder CDMA-Standard spielt keine Rolle. Nutze es via Roaming in GSM-Netzen in 200 Ländern weltweit.
 
Integrierte Apps. Machen alles, damit du alles machen kannst.
Ganz Alltägliches erledigst du mit dem iPhone 4S auf ganz außergewöhnliche Weise. Mach fantastische Fotos und nimm HD Videos auf. Sieh Freunde und Familie mit FaceTime. Tauche auf dem Retina Display richtig ins Web ein. Check deine Mails. Sende Nachrichten. Lege Erinnerungen fest. Schau in deinen Kalender. Oder sag Siri einfach, wie es dir helfen soll. Siri findet dann selbst heraus, welche Apps es verwenden muss.
Aufgrund der sehr umfangreichen Leistungsmerkmale können wir Ihnen hier nur einen Auszug präsentieren. Die vollständigen Funktionsbeschreibungen inkl. einer Vielzahl von Videos entnehmen Sie bitte der Herstellerwebseite.
•Apple iPhone 4S
•115,2 x 58,6 x 9,3 mm klein und 140 g leicht
•Kapazität: 16 GB Flash-Laufwerk
•Kamera, Fotos und Video:
• 8.0 Megapixel Kamera
• Videoaufnahme, HD (1080p) bis zu 30 fps mit Audio
• Fotos und Videos in VGA-Qualität mit bis zu 30 fps mit der Kamera an der Vorderseite
• Fokussieren per Fingertipp für Videos und Fotos LED-Blitz
• Geotagging für Fotos und Videos
•Display:
• Retina Display
• 3,5""-Multitouch-Display (8,89 cm Diagonale)
• Auflösung von 960 x 640 Pixeln mit 326ppi
• Typisches Kontrastverhältnis: 800:1
• Fettabweisende Beschichtung an der Vorder- und Rückseite
• Unterstützung für die Anzeige mehrerer Sprachen und Zeichen gleichzeitig
•Stromversorgung und Batterie:
• Sprechdauer: bis zu 8 Std. mit 3G, bis zu 14 Std. mit 2G
• Standbydauer: bis zu 200 Std.
• Internetnutzung: bis zu 6 Std. mit 3G, bis zu 9 Std. mit Wi-Fi
• Videowiedergabe: bis zu 10 Std., Audiowiedergabe: bis zu 40 Std.
•Betriebssystem: iOS 5
•Mobilfunknetz und Wi-Fi:
• UMTS/HSDPA/HSUPA (850, 900, 1900, 2100 MHz)
• GSM/Edge (850, 900, 1800, 1900 MHz)
• Funktechnologie: 802,11b/g/n Wi-Fi (802.11 nur mit 2,4 GHz), Bluetooth 4.0
•GPS: Assisted GPS
•Digitaler Kompass
•Unterstützte Audioformate: AAC (8 bis 320 KBit/Sek.), Protected AAC (aus dem iTunes Store), HE-AAC, MP3 (8 bis 320 KBit/Sek.), MP3 VBR, Audible (Formate 2, 3, 4, Audible Enhanced Audio, AAX und AAX+), Apple Lossless, AIFF und WAV
•TV und Video: AirPlay Mirroring to Apple TV support at 720p, Video mirroring and video out support: Up to 1080p with Apple Digital AV Adapter or Apple VGA Adapter (adapters sold separately), Video out support at 576p and 480p with Apple Component AV Cable; 576i and 480i with Apple Composite AV Cable (cables sold separately)
•Unterstützte Videoformate: H.264 Video: bis zu 720p, 30 Bilder pro Sekunde, Main Level Profile Level 3.1 mit AAC-LC Audio bis zu 160 KBit/Sek., 48 kHz, Stereo-Audio in den Formaten .m4v, .mp4 und .mov; MPEG.4 Video: bis zu 2,5 MBit/Sek., 640 x 480 Pixel, 30 Bilder pro Sekunde, Simple Profile mit AAC-LC Audio bis zu 160 KBit/Sek., 48 kHz, Stereo-Audio in den Formaten .m4v, .mp4 und .mov; Motion JPEG (M-JPEG): bis zu 35 MBit/Sek., 1280 x 720 Pixel, 30 Bilder pro Sekunde, Audio im Format ulaw, PCM Stereo-Audio im Format .avi
•Sensoren:
• 3-Achsen-Gyrosensor
• Beschleunigungssensor
• Annäherungssensor
• Umgebungslichtsensor
 
Lieferumfang:
iPhone 4S, Apple Earphones mit Fernbedienung und Mikrofon, Dock Connector-auf-USB-Kabel, Dokumentation
";2;False;0;;;"Apple iPhone 4S schwarz ";apple-iphone-4s-schwarz;True;True;PD-01081;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;639.0000;639.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40885,5442708333;71;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000651-apple-iphone-4s-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000652-apple-iphone-4s-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000653-apple-iphone-4s-schwarz.jpg;1;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;AVM FRITZ! Box WLAN 3270;AVM FRITZ! Box WLAN 3270 mit 300 Mbit/s und WLAN Eco-Mode;"
FRITZ!Box WLAN 3270
Einfach, sicher, kabellos surfen und vernetzen!
 
FRITZ!Box WLAN 3270 verbindet alle Ihre Computer mit dem Internet - rasend schnell über ADSL oder ADSL2+ und kabellos mit dem neuen WLAN 802.11n.
 
FRITZ!Box WLAN 3270 vereint ein DSL-Modem mit einem WLAN N-Router in einem Gerät. Mit modernem WLAN N bietet die FRITZ!Box übertragungsgeschwindigkeiten von bis zu 300 MBit/s beim kabellosen Surfen. Computer und netzwerkfähige Geräte lassen sich zudem über die vier Ethernet-Schnittstellen anschließen. Dank des USB-Anschlusses (USB 2.0) stehen Drucker und Speicher im ganzen Netzwerk zur Verfügung.
 
Ein Hi-Speed-USB 2.0-Anschluss und die erweiterte NAS-Funktionalität mit Mediaserver und Onlinespeicher-Integration erschließen neue Anwendungsmöglichkeiten im Netzwerk.
 
Damit sind Inhalte wie Filme, Musik und Bilder auch bei ausgeschaltetem Computer im gesamten Netzwerk verfügbar und können auf UPnP-AV-fähigen Geräten (z. B. HD-Fernseher oder Stereoanlage) wiedergegeben werden.
 
 FRITZ!Box WLAN 3270 verfügt über eine umfangreiche Softwareausstattung. Dazu gehören beispielsweise Firewall, Kindersicherung, VPN, WLAN-Nachtschaltung und WLAN-Autokanal.
 
WLAN N
FRITZ!Box WLAN 3270 ermöglicht WLAN-Verbindungen mit dem Funkstandard 802.11n im 2,4-GHz- oder im besonders störungsarmen 5-GHz-Band. Durch das Mehrantennenverfahren MIMO (Multiple Input Multiple Output) erhöhen sich Reichweite, Qualität und Datenrate der WLAN-Verbindung. FRITZ!Box WLAN 3270 ist bereits ab Werk sicher dank der voreingestellten, individuellen WPA-/WPA2-Verschlüsselung.
 
Energie sparen mit FRITZ!
Mit dem Eco-Mode passt FRITZ!Box WLAN 3270 die Funkleistung automatisch an den Datenverkehr an und sorgt für optimalen Stromverbrauch. Im Ruhezustand wird die Prozessorleistung minimiert und ungenutzte Schnittstellen werden abgeschaltet. Die Funkdauer kann dank der WLAN-Nachtschaltung beliebig eingestellt oder mit einem Schalter verändert werden.
 
Mehr Möglichkeiten mit USB 2.0
Ein Hi-Speed-USB 2.0-Anschluss ermöglicht neue Anwendungen im Netzwerk. Bilder, Musik und Videos von an der FRITZ!Box angeschlossenen Speichermedien können an UPnP-AV-kompatiblen Empfängern (HD-Fernseher, Stereoanlage) wiedergegeben werden. Zusätzlich kann ein USB-Drucker dem gesamten Netzwerk zur Verfügung gestellt werden.
 
Egal ob Online- oder USB-Speicher - die integrierte FRITZ!NAS-Webseite (http://fritz.nas) bietet eine einfache und komfortable Möglichkeit, zentral auf alle Datenbestände an der FRITZ!Box zuzugreifen. Auf Wunsch auch über das Internet.
 
Anschlüsse
- DSL-Anschluss an ADSL2+ und ADSL.
 
- Routerbetrieb auch mit Kabelmodem oder UMTS-Stick (UMTS/HSPA).
 
- WLAN-Funknetze nach gängigen Standards (802.11n/g/b/a).
 
- 4 x Ethernet (10/100 Base-T) für Anschluss und Vernetzung von Computern und Spielekonsolen.
 
- USB 2.0-Anschluss für USB-Geräte wie Drucker und Speichermedien oder UMTS-Stick.
";2;False;0;;;AVM FRITZ! Box WLAN 3270 mit 300 Mbit/s und WLAN Eco-Mode;avm-fritz-box-wlan-3270;True;True;P-2690;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;169.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40871,807349537;18;34;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000206-avm-fritz-box-wlan-3270.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000207-avm-fritz-box-wlan-3270.jpg;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;AVM FRITZ!Box Fon WLAN 7390;AVM FRITZ!Box Fon WLAN 7390;"
FRITZ!Box Fon WLAN 7390
Mehr Leistung für Internet, Telefon und digitale Medien.
 
FRITZ!Box Fon WLAN 7390 verbindet alle Ihre Computer mit dem Internet - rasend schnell über VDSL (bis 100 MBit/s) oder ADSL2+/ADSL (bis 16 MBit/s). Der neue WLAN-Standard 802.11n (WLAN N) sorgt für ein Maximum an Geschwindigkeit und Reichweite beim kabellosen Surfen. Und dank integrierter DECT-Basisstation und HD-Telefonie wird das Telefonieren über das Internet zu einem komfortablen Erlebnis.
 
FRITZ!Box Fon WLAN 7390 bietet eine bisher nicht erreichte Vielfalt an Anwendungen für den DSL-Anschluss. Der neue WLAN N-Funkstandard sorgt in Verbindung mit der MIMO- Mehrantennentechnik für eine optimale übertragung mit 2,4 und 5 GHz gleichzeitig (Dualband).
 
Für die Internet- und Festnetztelefonie steht neben Anschlüssen für analoge und ISDN- Telefone auch eine integrierte DECT-Basis- station für bis zu 6 Schnurlostelefone zur Verfügung.
 
FRITZ!Box Fon WLAN 7390 bietet dank leistungsstarkem Prozessor die Plattform für vernetzte Anwendungen wie IPTV, Video on Demand oder Mediastreaming.
 
 Zwei Hi-Speed-USB 2.0-Anschlüsse der FRITZ!Box Fon WLAN 7390 und die erweiterte NAS-Funktionalität mit Mediaserver und Onlinespeicher-Integration erschließen neue Anwendungsmöglichkeiten im Netzwerk. Damit sind Inhalte wie Filme, Musik und Bilder auch bei ausgeschaltetem Computer im gesamten Netzwerk verfügbar und können auf UPnP-AV-fähigen Geräten (z. B. HD-Fernseher oder Stereoanlage) wiedergegeben werden.
 
FRITZ!Box Fon WLAN 7390 verfügt über eine umfangreiche Softwareausstattung. Dazu gehören beispielsweise Telefonbuch, Firewall, Kindersicherung, Faxempfang, VPN, WLAN-Nachtschaltung, WLAN-Autokanal oder ein integrierter Anrufbeantworter.
 
Dual-WLAN N
FRITZ!Box Fon WLAN 7390 ermöglicht WLAN-Verbindungen mit dem Funkstandard 802.11n im 2,4-GHz- und im besonders störungsarmen 5-GHz-Band gleichzeitig. Durch das Mehrantennenverfahren MIMO (Multiple Input Multiple Output) erhöhen sich Reichweite, Qualität und Datenrate der WLAN-Verbindung. FRITZ!Box Fon WLAN 7390 ist bereits ab Werk sicher dank der voreingestellten, individuellen WPA-/WPA2-Verschlüsselung.
 
DECT-Basisstation
Durch die integrierte DECT-Basisstation können Sie mit bis zu sechs Mobilteilen schnurlos telefonieren. Als ideale Ergänzung zur FRITZ!Box Fon WLAN 7390 bietet AVM die schnurlosen Telefone FRITZ!Fon MT-D und MT-F an, mit denen zahlreiche Komfortfunktionen sowie brillante HD-Telefonie genutzt werden können.
 
Energie sparen mit FRITZ!
Mit dem Eco-Mode passt FRITZ!Box Fon WLAN 7390 die Funkleistung automatisch an den Datenverkehr an und sorgt für optimalen Stromverbrauch. Im Ruhezustand wird die Prozessorleistung minimiert und ungenutzte Schnittstellen werden abgeschaltet. Die Funkdauer kann dank der WLAN-Nachtschaltung beliebig eingestellt oder mit einem Schalter verändert werden.
 
Mehr Möglichkeiten mit USB 2.0
Zwei Hi-Speed-USB 2.0-Anschlüsse ermöglichen neue Anwendungen im Netzwerk. Bilder, Musik und Videos von an der FRITZ!Box angeschlossenen Speichermedien können an UPnP-AV-kompatiblen Empfängern (HD-Fernseher, Stereoanlage) wiedergegeben werden. Zusätzlich kann ein USB-Drucker dem gesamten Netzwerk zur Verfügung gestellt werden.
 
Egal ob interner, Online- oder USB-Speicher - die integrierte FRITZ!NAS-Webseite (http://fritz.nas) bietet eine einfache und komfortable Möglichkeit, zentral auf alle Datenbestände an der FRITZ!Box zuzugreifen. Auf Wunsch auch über das Internet.
 
7390-3.jpg
";2;False;0;;;AVM FRITZ!Box Fon WLAN 7390;avm-fritzbox-fon-wlan-7390;True;True;P-2700;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;289.0000;289.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40871,8066898148;18;34;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000103-avm-fritzbox-fon-wlan-7390.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000104-avm-fritzbox-fon-wlan-7390.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000105-avm-fritzbox-fon-wlan-7390.jpg;1;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"AVM FRITZ!Box Fon WLAN 7270 ";"AVM FRITZ!Box Fon WLAN 7270 ";"
FRITZ!Box Fon WLAN 7270
Kabellos mit DSL surfen und über das Internet telefonieren.
 
FRITZ!Box Fon WLAN 7270 verbindet alle Ihre Computer mit dem Internet - rasend schnell über ADSL oder ADSL2+ und kabellos mit dem neuen WLAN 802.11n.
 
FRITZ!Box Fon WLAN 7270 vereint DSL-Modem und WLAN-Router mit einer Telefonanlage für Internet- (VoIP-) und Festnetztelefonie und kann wahlweise an analogen oder ISDN-Anschlüssen eingesetzt werden. Sowohl analoge als auch ISDN- und DECT-Telefone werden durch FRITZ!Box Fon WLAN 7270 mit dem Internet und Festnetz verbunden. Das können bis zu zwei analoge Endgeräte wie Telefon und Fax sein, eine ISDN-TK-Anlage, aber auch bis zu sechs Schnurlostelefone, die sich einfach mit der in der FRITZ!Box Fon WLAN 7270 integrierten DECT-Basisstation verbinden lassen.
 
Unabhängig von der Art des Anschlusses stehen alle wesentlichen Leistungsmerkmale wie Rufnummernanzeige, Dreierkonferenz, Rufumleitung und Makeln an den Telefonen zur Verfügung. Internettelefonie in HD-Qualität (High Definition) wird durch den Einsatz von Breitband-Sprachcodecs unterstützt.
 
 FRITZ!Box Fon WLAN 7270 bietet mit modernem WLAN N übertragungsgeschwindigkeiten von bis zu 300 MBit/s. Computer und netzwerkfähige Geräte lassen sich zudem über die vier LAN-Schnittstellen anschließen. Dank des USB-Anschlusses (USB 2.0) stehen Drucker und Speicher im ganzen Netzwerk zur Verfügung.
 
FRITZ!Box Fon WLAN 7270 verfügt über eine umfangreiche Softwareausstattung. Dazu gehören beispielsweise Telefonbuch, integrierter Anrufbeantworter, Faxempfang, WLAN-Nachtschaltung, Kindersicherung und VPN.
 
WLAN N
FRITZ!Box Fon WLAN 7270 ermöglicht WLAN-Verbindungen mit dem Funkstandard 802.11n im 2,4-GHz- oder im besonders störungsarmen 5-GHz-Band. Durch das Mehrantennenverfahren MIMO (Multiple Input Multiple Output) erhöhen sich Reichweite, Qualität und Datenrate der WLAN-Verbindung. FRITZ!Box Fon WLAN 7270 ist bereits ab Werk sicher dank der voreingestellten, individuellen WPA-/WPA2-Verschlüsselung.
 
DECT-Basisstation
Durch die integrierte DECT-Basisstation können Sie mit bis zu sechs Mobilteilen schnurlos telefonieren, wenn diese den Standard CAT-iq oder GAP unterstützen. Als ideale Ergänzungen zur FRITZ!Box bietet AVM die schnurlosen Telefone FRITZ!Fon MT-F und FRITZ!Fon MT-D an, mit denen Sie zahlreiche Komfortfunktionen sowie Internettelefonie in HD-Qualität nutzen können.
 
Energie sparen mit FRITZ!
Mit dem Eco-Mode passt FRITZ!Box Fon WLAN 7270 die Funkleistung automatisch an den Datenverkehr an und sorgt für optimalen Stromverbrauch. Im Ruhezustand wird die Prozessorleistung minimiert und ungenutzte Schnittstellen werden abgeschaltet. Die Funkdauer kann dank der WLAN-Nachtschaltung beliebig eingestellt oder mit einem Schalter verändert werden.
 
Mehr Möglichkeiten mit USB 2.0
Ein Hi-Speed-USB 2.0-Anschluss ermöglicht neue Anwendungen im Netzwerk. Bilder, Musik und Videos von an der FRITZ!Box angeschlossenen Speichermedien können an UPnP-AV-kompatiblen Empfängern (HD-Fernseher, Stereoanlage) wiedergegeben werden. Zusätzlich kann ein USB-Drucker dem gesamten Netzwerk zur Verfügung gestellt werden.
 
Egal ob Online- oder USB-Speicher - die integrierte FRITZ!NAS-Webseite (http://fritz.nas) bietet eine einfache und komfortable Möglichkeit, zentral auf alle Datenbestände an der FRITZ!Box zuzugreifen. Auf Wunsch auch über das Internet.
";2;False;0;;;AVM FRITZ!Box Fon WLAN 7270 N-Standard mit bis zu 300 MBit/Sek;avm-fritzbox-fon-wlan-7270;True;True;;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;249.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40871,8016898148;18;34;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000200-avm-fritzbox-fon-wlan-7270.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000201-avm-fritzbox-fon-wlan-7270.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000202-avm-fritzbox-fon-wlan-7270.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Samsung SyncMaster P2270 HD 22 Zoll TFT Monitor ";Samsung SyncMaster P2270 HD 22 Zoll TFT Monitor schwarz;"
Samsung P2270HD
Die SyncMaster 70er HD-Serie besticht mit edlem Design und technischen Raffinessen: So können die Modelle dieser Serie als LCD-Monitor, aber auch als vollwertiges LCD-TV-Gerät eingesetzt werden. Der integrierte TV Tuner macht es möglich. Vielseitige AV-Anschlussmöglichkeiten bieten zudem die Möglichkeit, weitere Peripheriegeräte anzuschließen. Das praktische 16:9-Format mit Full HD Auflösung und die Unterstützung von Dolby Digital Plus und SRS TruSurround HD runden die multimedialen Eigenschaften dieser Serie ab.
 
TV Tuner
Dieses SyncMaster-Modell ist mit einem TV Tuner ausgestattet und kann somit auch als vollwertiges LCD-TV-Gerät verwendet werden.
 
16:9-Widescreen-Format
Das praktische 16:9-Widescreen-Format ermöglicht ein noch angenehmeres Arbeiten bei gleichzeitiger Steigerung Ihrer Produktivität. Das Breitbildformat entspricht dem natürlichen Sichtfeld des Betrachters. Somit haben Sie immer alles im Blick, ohne auf wichtige Informationen verzichten zu müssen.
 
Full HD
Dieses SyncMaster Large Format Display verfügt über ein Full HD Panel mit einer nativen Auflösung von 1.920 x 1.080 Pixel. Somit können Bildinhalte im 1.080p-Format, der derzeit besten HD-Auflösung, wiedergegeben werden. 
 
Dynamischer Kontrast
Genießen Sie beste Bildqualität mit hoher Bildschärfe und Detailreichtum selbst in dunklen Szenen. Mit einem dynamischen Kontrast von bis zu 50.000:1 werden Sie jedes Detail auf dem Bildschirm erkennen können.
 
HDMI
HDMI steht für High Definition Multimedia Interface. Mit dieser Schnittstelle ist es möglich, HD Bild- und Tonmaterial in 100% verlustfreier, digitaler Qualität zu übertragen.
 
MagicSpeed
MagicSpeed garantiert Ihnen selbst bei schnell bewegten Bildschirminhalten, wie z. B. Filmen oder Computerspielen, eine schlierenfreie Darstellung für beste Bildqualität. 
  
HDCP
HDCP oder auch High Bandwidth Digital Content Protection schützt urheberrechtlich geschützte Formate (z. B. Videodaten) vor illegalen Kopien. HDCP muss dabei sowohl vom Quellgerät (z. B. DVD-Player) als auch vom Ausgabegerät (Monitor) unterstützt werden. Dieses SyncMaster-Modell ist HDCP-kompatibel.
 
Energiesparfunktion
Samsung Displays, die dieses Logo tragen, sind besonders energieeffizient und schonen somit die Umwelt.
 
RoHS-Zertifikat
Die Displays von Samsung wurden von Nemko mit dem RoHS-Logo zertifiziert, d. h. sie enthalten keine gefährlichen Substanzen gemäß den Richtlinien der Europäischen Union. Damit ist Samsung der erste Hersteller am Markt, der offiziell diese Zertifizierung erhalten hat. 
 
";2;False;0;;;Samsung SyncMaster P2270 HD 22 Zoll;samsung-syncmaster-p2270-hd-22-zoll-tft-monitor;True;True;P-2480;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;199.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40871,5791087963;9;5;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000462-samsung-syncmaster-p2270-hd-22-zoll-tft-monitor.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000463-samsung-syncmaster-p2270-hd-22-zoll-tft-monitor.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000464-samsung-syncmaster-p2270-hd-22-zoll-tft-monitor.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Apple iPod Touch 8 GB schwarz;Apple iPod Touch 8 GB schwarz;"
Apple iPod Touch 8 GB schwarz
 
mit integrierter WiFi Funktion

 
Ein großartiger iPod. Ein großartiger Taschencomputer. Großartiger mobiler Spielspaß. Und das Ganze in einem unglaublich schlanken, eleganten neuen Design aus Edelstahl. Filme, Videos und Fernsehsendungen auf einem 3,5"" Display ansehen!Im Web surfen, mailen! Multitouch-Oberfläche: Die revolutionäre Technologie des iPhone und die Software Version 3.1 stecken in diesem genialen iPod. Das brillante Breitformat-Display rückt Ihre Videos und Spiele ins beste Licht Surfen Sie mit Safari im Web und sehen Sie YouTube Videos auf dem iPod mit integrierter Wi-Fi Funktionalität an.
 
Mit Ihrem iPod touch können Sie im iTunes Wi-Fi Music Store nach Songs suchen, Hörproben abspielen und Titel kaufen.  Lieferumfang: iPod touch, Ohrhörer, USB 2.0 Kabel, Dock-Adapter, Kurzanleitung
 
Der iPod touch kann alles, was du am iPod toll findest. Und noch vielmehr.
Du kannst Filme, Videos und Fernsehsendungen auf einem 3,5"" Display ansehen. Mit der revolutionären Multi-Touch-Technologie kannst du dein Musikarchiv mit Cover Flow durchblättern. Und wenn dir nach mehr ist, tipp einfach auf iTunes, um durch das Angebot zu stöbern und sofort einzukaufen. Hör dir Wiedergabelisten an, die automatisch für dich erstellt werden. Schau Filme auf dem brillanten 3,5"" Display. Und kauf mit einem Fingertipp bei iTunes ein - wann immer du willst. All das und noch viel mehr mit dem iPod touch, den es schon ab 189 € gibt. Wi-Fi ist schon integriert. So kannst du im Web surfen, mailen, deinen Facebook Status aktualisieren, mit AIM chatten und noch viel mehr - und das alles auf einem Gerät, das locker in jede Tasche passt. Hier hast du die Finger im Spiel. Und nicht nur die. Denn mit den Spielen auf dem iPod touch tauchst du richtig in die Action ein - einfach neigen, tippen, drehen. Und via Wi-Fi kannst du jederzeit im App Store neue Spiele kaufen. Die iPhone 3.1 Software ist auf dem iPod touch bereits installiert, sodass der Spaß gleich beginnen kann. Damit kannst du nützliche Funktionen wie Peer-to-Peer-Spiele und Cut, Copy & Paste direkt nach dem Auspacken nutzen.
Next Level Fun: Der neue iPod touch
 
Musik
Stöber durch deine Alben. Hör dir einen einzigartigen Mix an, der nur für dich erstellt wurde. Oder schau das Video deines Lieblingssongs an. Mit dem iPod touch kannst du mehr als nur Musik hören.
 
Cover Flow
Auf dem iPod touch gibt's Musik nicht nur auf die Ohren. Mit Cover Flow ist Musik auch etwas für Augen und Finger. Dreh den iPod touch einfach auf die Seite und blätter durch deine Albumcover. Tipp auf ein Albumcover, um es umzudrehen und die Songliste zu sehen. Tipp noch einmal und Musik ab.
 
Genius Mixe
Die Genius Funktion wurde weiter verbessert. Jetzt gibt es Genius Mixe. Du brauchst den iPod touch nur mit iTunes zu synchronisieren. Genius durchsucht dann automatisch deine Mediathek nach Songs, die gut zusammenpassen und erstellt bis zu zwölf Mixe.
Diese Mixe sind wie Radiosender, auf denen nur deine Musik läuft.
 
Genius Wiedergabelisten
Angenommen du hörst einen Song auf deinem iPod touch, der dir gut gefällt, und du möchtest weitere Titel hören, die dazu passen. Genius findet weitere Songs auf deinem iPod touch und erstellt eine Genius Wiedergabeliste für dich. Hör dir die Wiedergabeliste sofort an, speichere sie für später oder versuch's noch einmal und sieh, was dabei herauskommt. Verlass dich auf Genius, wenn du einen Mix willst, auf den du selbst nie gekommen wärst.
 
Shake to Shuffle
Die Dinge mal aufrütteln. Musikalisch natürlich. Wenn du das nächste Mal Musik hörst, aktiviere die Schüttelfunktion und wenn du den iPod touch dann kurz schüttelst, springt er nach dem Zufallsprinzip zu einem anderen Song aus deiner Sammlung.
 
iTunes
Pack Musik und Videos aus der iTunes Mediathek deines Computers auf den iPod touch. Oder kauf und lade neue Songs auf den iPod touch, wenn du über Wi-Fi auf iTunes zugreifst. Wenn du den iPod touch das nächste Mal mit dem Computer verbindest, werden alle Songs, die du auf dem iPod touch gekauft hast, auf den Mac oder PC übertragen.
 
Bluetooth
Schau mal, keine Kabel. Der iPod touch enthält die iPhone 3.1 Software, sodass du Bluetooth Stereokopfhörer anschließen kannst. Lass den iPod in deiner Tasche stecken oder auf dem Schreibtisch aufladen, während du weiter Musik hörst.
 
Filme und Fernsehsendungen
Ein Kinohit. Ein Video-Podcast. Deine Lieblingsserie. Jetzt laufen sie auch in einer U-Bahn oder einem Flugzeug in deiner Nähe.
Widescreen-Display
Du kannst Videos für viele Stunden überallhin mitnehmen und auf dem gestochen scharfen 3,5"" Widescreen-Farbdisplay ansehen. Kauf im iTunes Store und wähle unter tausenden vonFilmen, Fernsehsendungen und Video-Podcasts, die du auf den iPod touch laden kannst. Von Hollywood-Hits bis zu Indie-Streifen - es gibt etwas für jeden Geschmack. Mit wenigen Fingertipps kannst du Filme kaufen und laden. Du magst lieber Fernsehsendungen? Lade eine einzelne Folge oder die gesamte Staffel.
 
On-Screen Steuerung
Auch während du Video guckst, kannst du die Steuerung einblenden - ein Fingertipp auf das Display genügt. Du kannst die Wiedergabe starten oder unterbrechen, einzelne Kapitel anzeigen und die Lautstärke anpassen. Natürlich kannst du auch die Lautstärkeregler links am iPod touch verwenden. Du willst zwischen Widescreen und bildschirmfüllender Anzeige wechseln? Einfach aufs Display doppeltippen.
 
iTunes
Du brauchst Unterhaltung für deinen nächsten Flug oder die Autofahrt? Mit iTunes auf dem iPod touch und einer Wi-Fi-Verbindung kannst du auch unterwegsFilme und Fernsehsendungen kaufen. Du kannst Filme auch leihen, wenn du dir nicht sicher bist, ob du den Film behalten willst. Und natürlich kannst du Filme und Fernsehsendungen auf dem Mac oder PC kaufen und dann mit dem iPod touch synchronisieren.
 
App Store
Kaufe im App Store und entdecke über 65.000 Apps, mit denen du noch mehr auf dem iPod touch machen kannst. Stöbere in tausenden von Apps in verschiedenen Kategorien. Von Spielen über Lifestyle und Soziale Netzwerke bis zu Unterhaltung und mehr.
 
Apps durchstöbern
Du kannst auf verschiedene Arten im App Store shoppen. Tipp auf ""Neu"" und ""Topaktuell"", um eine Liste der aktuellen und angesagten Apps zu erhalten. Stöbere nach Kategorien. Schau dir die topaktuellen Apps an. Wenn du genau weißt, wonach du suchst, kannst du auch eine Schnellsuche durchführen.
 
Genius Empfehlungen für Apps
Es gibt tausende von Apps im App Store, und jeden Tag kommen mehr dazu. Mit dieser neuen Funktion des iPod touch findest du coole neue Apps noch einfacher. Genius für Apps. Funktioniert genau wie Genius für deine Musik. Tipp auf das Genius Symbol und du bekommst Empfehlungen für Apps anhand der Apps, die du und andere schon geladen haben.
 
Apps laden
Wenn du eine App findest, die dich interessiert, kannst du sie überall, wo eine Wi-Fi-Verbindung besteht, drahtlos kaufen, auf den iPod laden und dann sofort loslegen.
 
Updates für Apps
iPod touch sagt dir, wenn ein App Update verfügbar ist, damit du immer die neuesten Versionen deiner Lieblings-Apps hast.
 
iTunes
Entdecke und lade neue Musik, Filme, Fernsehsendungen, Podcasts und Hörbücher in iTunes auf dem iPod touch.
 
Einkaufen, immer und überall
Greif über die im iPod touch integrierte Wi-Fi-Funktion auf den iTunes Store zu. Durchsuche Millionen von iTunes Plus Songs in brillanter Audioqualitätund tausende von Filmen, Fernsehsendungen, Hörbüchern und kostenlosen Podcasts und Vorlesungen von iTunes U. Stöbere nach Neuerscheinungen, Top-Titeln und Genres. Oder finde mit der Schnellsuche genau das, wonach du suchst. Hör in einen Song oder sieh dir eine Videovorschau an. Wenn du dann etwas kaufen möchtest, brauchst du nur darauf zu tippen. Nicht sicher, ob es sich lohnt, den Film zu kaufen? Dann leih ihn einfach. Alles was du auf dem iPod touch kaufst, hat denselben Preis wie im iTunes Store auf deinem Computer.
 
Synchronisieren mit iTunes
Sobald du den iPod touch mit dem Computer verbindest, werden die Songs, Filme, Fernsehsendungen, Hörbücher und Podcasts, die du unterwegs geladen hast, mit deiner iTunes Mediathek auf deinem Mac oder PC synchronisiert. Wenn du etwas nur teilweise auf den iPod touch geladen hast, beendet der Computer den Download automatisch für dich.
 
Sprachsteuerung
Mit der Sprachsteuerung beim neuen 32 GB und 64 GB iPod touch kannst du deine Musik mit Sprachbefehlen steuern. Und der iPod hört aufs Wort. Auf ""Spiel"", ""Shuffle"" oder ""Wie heißt das Lied?"".
 
Sagen und abspielen.
Die Sprachsteuerung kennt die Musik auf deinem iPod touch. Wenn du etwas Bestimmtes hören willst, sag es einfach. Zum Beispiel ""Spiel Bob Dylan"" und der iPod touch hört aufs Wort. Frag ihn, welcher Song grad läuft, und der iPod touch sagt es dir. Sag ihm, dass er dein Lieblingsalbum, deinen Lieblingssänger oder deine Lieblingswiedergabeliste spielen soll. Verwende einfache Befehle wie ""shuffle"", ""nächster Song"" und ""anhalten"". Du kannst dem iPod touch sogar sagen, dass er mehr Songs wie den, der gerade läuft, abspielen soll.
 
Sprich ins Mikro
Der neue 32 GB und 64 GB iPod touch wird mit den Apple Earphones mit Fernbedienung und Mikro geliefert. So kannst du die Sprachsteuerung auch dann nutzen, wenn der iPod touch in der Tasche steckt. Zum Aktivieren der Sprachsteuerung über die Kopfhörer hältst du einfach die Mitteltaste der Fernbedienung gedrückt.
 
Die Sprachsteuerung unterstützt die folgenden Sprachen:
Chinesisch (China), Chinesisch (Kantonesisch), Chinesisch (Taiwan), Deutsch, Englisch (Großbritannien), Englisch (USA), Finnisch, Französisch (Frankreich), Französisch (Kanada), Italienisch, Japanisch, Koreanisch, Niederländisch, Norwegisch, Polnisch, Portugiesisch (Brasilien), Portugiesisch (Portugal), Russisch, Schwedisch, Spanisch (Mexiko), Spanisch (Spanien)
 
Fotos
Der iPod touch hat für bis zu 90.000 deiner Lieblingsfotos Platz. Durch Streichen kannst du sie durchschauen und all die Erinnerst-du-dich-noch-Momente mit anderen teilen.
 
Fotos sichern
Wenn dir tolle Bilder gemailt werden, kannst du sie einfach im Fotoarchiv auf dem iPod touch sichern und dann wie jedes andere Foto nutzen. Du kannst sie zum Beispiel als Hintergrundbilder verwenden, im Internet teilen oder weitergeben.
 
Fotos teilen
Du hast tausende Fotos immer zur Hand. Blätter durch Streichen auf dem Display durch Miniaturen. Mit einem Fingertipp siehst du Fotos bildschirmfüllend. Spiel Diashows mit Musik und Übergängen ab. Maile Fotos an Freunde oder teile sie in einer MobileMe Galerie.
 
Fotos synchronisieren
Fotos aus iPhoto auf einem Mac oder Adobe Photoshop Elements und Adobe Photoshop Album auf einem PC werden via iTunes mit dem iPod touch synchronisiert. Einfach nur die Fotos und Alben aussuchen, die mit dem iPod touch synchronisiert werden sollen. Dann kannst du sie überall ansehen und mit anderen teilen.
 
Homescreen
Angenommen du möchtest ""Karten"" als erste App in der zweiten Zeile haben. Oder Mail unten im Dock. Mit den anpassbaren Homescreens kannst du den iPod touch zu deinem iPod touch machen.
 
Individuelles Anpassen
Ordne die Symbole auf deinem Homescreen an wie du willst - direkt auf dem iPod touch oder auf deinem Computer in iTunes 9. Bewege eine App eine Zeile nach oben, zwei Apps nach rechts oder auf einen anderen Homescreen. Du kannst bis zu 11 Homescreens erstellen und hast so schnellen Zugriff auf Spiele und Apps, die du aus dem App Store lädst, und auf deine Safari Weblinks.
 
Hometaste
Was auch immer du gerade mit deinem iPod touch machst – die Hometaste bringt dich immer zurück zum ersten Homescreen. Wenn du auf die Hometaste drückst, kannst du von jedem Homescreen wieder zurück zum ersten springen.
 
Apps und Weblinks hinzufügen
Für jede App, die du aus dem App Store lädst, erscheint ein neues Symbol auf dem Homescreen. Von häufig besuchten Websites kannst du praktische Weblinks erstellen. Sie erscheinen auf dem Homescreen und du kannst per Fingertipp darauf zugreifen.
 
Spotlight Suche
Du suchst was? Von einem Ort aus kannst du die gesamten Inhalte des iPod touch durchsuchen. Streich auf dem ersten Homescreen einfach nach rechts, um Spotlight zu öffnen. Sobald du anfängst zu tippen, durchsucht Spotlight deine gesamten Songs, Videos, Kontakte, Mails, Kalender, Notizen und sogar deine Hörbücher und Podcasts.
 
Safari
Safari, der fortschrittlichste Webbrowser auf einem Mobilgerät, ist auch auf dem iPod touch integriert. Damit erlebst du das Internet in deiner Hand genauso wie auf dem Computer zuhause. Alles was du brauchst ist eine Wi-Fi-Verbindung.
 
Überall ins Internet
Der iPod touch ist der einzige iPod mit integriertem drahtlosen Internetzugriff. Bei bestehender Wi-Fi-Verbindung kannst du im Internet surfen und Nachrichten lesen, Sportergebnisse sehen, Rechnungen bezahlen und online einkaufen. Und beim 32 GB oder 64 GB iPod touch wirst du sehen, dass Webseiten jetzt noch schneller als vorher geladen werden.
 
Im Web stöbern
Der iPod touch synchronisiert deine Lesezeichen vom PC oder Mac, sodass du ruckzuck auf deine Lieblingsseiten zugreifen kannst. Außerdem ist die Google- und Yahoo!-Suche schon integriert, sodass du im Web schnell findest, was du suchst.
 
Weblinks
Wenn du eine Website öfter besuchst - etwa die einer Zeitung, eines Blogs oder eine Sport-Website - kannst du einfach ein Symbol, einen sogenannten Weblink, auf dem Homescreen erstellen. Wenn du mit Safari Weblinks erstellst, sind deine Lieblingsseiten nur einen Fingertipp entfernt.
 
Zoom
Wenn du eine Website öfter besuchst, brauchst du nur mit dem Finger auf das Multi-Touch-Display zu tippen oder die Anzeige aufzuziehen. Websites lassen sich im Hoch- oder Querformat anzeigen. Einfach den iPod touch um 90 Grad drehen, und schon wird auch die Darstellung der Webseite gedreht.
 
Mail
Mails auf dem iPod touch funktionieren genau wie auf deinem Computer und sehen auch genau so aus. Und sie funktionieren mit deinen vorhandenen Accounts.
 
Nachrichten und Anhänge ansehen
Der iPod touch unterstützt Rich-HTML-E-Mail, sodass Bilder und Fotos zusammen mit dem Text einer E-Mail angezeigt werden. Anhänge siehst du in ihrem Originalformat und nicht als abgespeckte Version. Du kannst in mehr als einem Dutzend standardmäßigen Datei- und Bildformaten drehen, zoomen und schwenken, darunter PDF, Microsoft Word, Excel, PowerPoint und iWork.
 
Zugriff auf alle Accounts
Mails von gängigen Anbietern wie MobileMe, Google Mail, Microsoft Exchange, Yahoo! und den meisten standardmäßigen IMAP- und POP-Systemen kannst du mit dem iPod touch ganz einfach abrufen.
 
Schnellere Eingabe
Der iPod touch erkennt E-Mail-Adressen in verschiedenen Programmen. Wenn du auf einer Webseite oder in einer Karte eine E-Mail-Adresse siehst, reicht ein Fingertipp auf dem iPod touch, um eine neue Mail zu öffnen, in der die Adresse bereits eingetragen ist.
 
Intelligente Eingabe
Die innovative iPod touch Tastatur mit integriertem Wörterbuch* schlägt während der Eingabe Wörter vor. So kannst du ganz schnell und einfach Mails schreiben. Dreh den iPod touch einfach. Dann wird die Tastatur vom Hochformat ins Querformat gedreht und du hast größere Tasten und mehr Platz zum Tippen.
 
Postfach durchsuchen
Du musst das Postfach jetzt nicht mehr Mail für Mail durchsuchen. Durch schnelles Abwärtsstreichen wird jetzt ein Suchfeld geöffnet, mit dem du deine Mails nach Absender, Empfänger, Betreff oder Titelzeilen durchsuchen kannst.
 
Karten
Finde deinen Weg und die nächste Pizzeria. Mit Karten und einer Wi-Fi-Verbindung kannst du Wegbeschreibungen abrufen, Firmen finden und Verkehrsinformationen prüfen.
 
Finde dich selbst
Der iPod touch zeigt dir mithilfe von bekannten Wi-Fi-Hot-Spots, wo du bist. Mit der Stichwortsuche kannst du auch interessante Orte finden. Wenn du z. B. ""Kaffee"" eingibst, werden dir alle Cafés in der Nähe angezeigt.
 
Wo geht's lang?
Gib einfach eine Adresse ein, um Wegbeschreibungen abzurufen - von jedem Ort aus. Wähle das Transportmittel wie Auto, öffentliches Verkehrsmittel oder zu Fuß. Die Route lässt sich dann Schritt für Schritt anzeigen. Du kannst dem markierten Weg auf der Karte folgen und selbst die Fahrtdauer wird angezeigt. Oder markiere zwei Orte und lass dir die beste Route zwischen diesen anzeigen.
 
Verschiedene Kartendarstellungen
Wie bei Google Karten auf deinem Computer kannst du mit dem Programm ""Karten"" auf dem iPod touch zwischen unterschiedlichen Darstellungen von Google-Karten, Satellitenbildern und einer Hybriddarstellung wechseln. Und mit Multi-Touch kannst du unterwegs zoomen, den Ausschnitt bewegen und die Darstellung ändern.
 
Verkehrsinformationen
Die Verkehrsinformationen geben dir anhand der grünen, roten und gelben Markierungen einen Überblick über die Verkehrssituation auf deiner Route.
 
YouTube
Skateboard Moves, die so nicht geplant waren. Witzige Werbespots aus anderen Ländern. Was auch immer du gern auf YouTube ansiehst - der iPod touch ist für dich da.
 
Videogrüße von unterwegs.
Maile Links deiner Lieblingsvideos an Freunde. Tippe auf der Detailseite des YouTube Videos auf ""Senden"", und schon erstellt der iPod touch eine Mail mit dem zugehörigen Videolink.
 
Auf YouTube suchen.
Stöber in Videokategorien wie ""Highlights"", ""Topvideos"", ""Neue Videos"" oder ""Bestwertung"". Du kannst auch per Schlagwort nach einem Video suchen. Etwas Passendes gefunden? Mit einem Lesezeichen kannst du das Video auch vormerken und später ansehen.
 
Nike + iPod Kompatibilität
Rock dein Training. Der iPod touch hat eine integrierte Unterstützung für Nike + iPod. Das ist Musik und Motivation in einem.
Finetuning für dein Lauftraining.
 
Nike + iPod Sensor
Der iPod touch hat eine integrierte Unterstützung für Nike + iPod. Einfach den Nike + iPod Sensor (separat erhältlich) in die Nike+ Schuhe stecken und los geht's. Der Sensor überträgt deine Laufdaten drahtlos an den iPod touch und zeichnet Laufzeit, Laufstrecke und Kalorienverbrauch auf. Du erhältst sogar Feedback zum Trainingsfortschritt.
 
Finetuning für dein Cardio Workout
Diese Funktion kann auch zusammen mit neuen, in vielen Fitnessstudios vorhandenen Geräten für das Ausdauertraining gekoppelt werden. Such dir einfach ein mit Nike + iPod kompatibles Fitnessgerät wie beispielsweise Laufbänder, Ellipsentrainer, Stepper und Hometrainer.
 
Synchronisieren mit nikeplus.com
Später kannst du am Computer den iPod touch via iTunes synchronisieren und deine Trainingsdaten an nikeplus.com übertragen. Auf dieser Website kannst du dein Training verfolgen, dir Ziele setzen und deine Freunde herausfordern.
 
Sprachmemos
Du hast vielleicht ein ganz gutes Gedächtnis, aber manchmal ist es besser, kleine (und große) Infos einfach irgendwo festzuhalten. Mit ""Sprachmemos"" kein Problem.
 
Memos (oder alles andere)aufnehmen
Nimm eine Aufgabenliste, geniale Ideen oder eine Wette zwischen dir und deinem Freund auf. Mit dem Programm ""Sprachmemos"" kannst du über die Apple Earphones mit Fernbedienung und Mikro oder ein externes Mikrofon aufnehmen, was immer du willst. Sprachmemos kannst du selbst dann aufnehmen, wenn du den iPod touch gerade verwendest, um Mails zu checken oder im Web zu surfen.
 
Memos bearbeiten
Aufgenommene Memos kannst du direkt auf dem iPod touch trimmen. So behältst du nur das, was du wirklich brauchst.
 
Memos sortieren
Ordne deine Memos mithilfe von Etiketten aus einer vordefinierten Liste oder erstelle eigene Etiketten.
 
Memos teilen
Maile Memos an Freunde und Kollegen. Mit dem iPod touch aufgenommene Memos werden via iTunes mit deinem Mac oder PC synchronisiert, damit du sie später mit anderen teilen kannst.
 
Weitere Funktionen
Auf dem iPod touch ist die neueste Software schon installiert. Und außerdem gibt's praktische Apps wie Kontakte, Kalender, Notizen, Aktien und Wetter.
 
iPod touch 3.1 Softwarefunktionen.
 
Genius Mixe
Diese neue Funktion ist wie ein privater DJ, der deine iTunes Mediathek durchsucht, um Songs zu finden, die gut zusammenpassen und aus diesen dann tolle Mixe erstellt. Alles ganz automatisch.
 
Genius Empfehlungen für Apps
Im App Store gibt's zehntausende Apps. Wie soll man da die richtig collen neuen finden? Mit Genius. Denn Genius sieht sich die Apps an, die du schon hast, und empfiehlt dir weitere.
 
Peer-to-Peer-Spiele
Die neusten Spiele kannst du ganz leicht mit Freunden spielen - egal, ob sie neben dir oder in einer anderen Ecke des Landes sitzen.
 
Kauf Filme, Fernsehsendungen und Hörbücher via Wi-Fi
Lade via Wi-Fi Filme, Fernsehsendungen, Musikvideos und Hörbücher aus dem iTunes Store auf deinen iPod touch.
 
Tastatur im Querformat
Du brauchst mehr Platz zum Tippen? Dreh den iPod touch ins Querformat, um in Mail, Notizen und Safari mit einer größeren Tastatur zu arbeiten.
 
Cut, Copy & Paste
Einfach Text und Fotos ausschneiden, kopieren und wieder einsetzen - selbst zwischen Programmen. Du kannst auch Inhalte aus dem Web kopieren.
 
Spotlight Suche
Gesucht, gefunden - von einem Ort aus. Spotlight durchsucht alle deine Kontakte, E-Mails, Kalender und Notizen und auch alle Songs und Videos.
 
Stereo Bluetooth
Hör Musik und andere Audioinhalte drahtlos. Verbinde den iPod touch mit kompatiblen Bluetooth Stereokopfhörern.
 
Automatischer Wi-Fi-Login
Wenn du dich einmal bei einem Wi-Fi-Hotspot anmeldest, loggt der iPod touch sich beim nächsten Mal automatisch ein.
 
Shake to Shuffle
Schüttel den iPod kurz, und schon springt er nach dem Zufallsprinzip zu einem anderen Song in deiner Sammlung. Lass dich einfach überraschen.
 
Bedienungshilfen
Der neue iPod touch hat standardmäßig Bedienungshilfen integriert, mit denen auch Menschen mit Beeinträchtigungen alles, was der iPod touch zu bieten hat, erleben können. Alle Bedienungshilfen des iPod touch ansehen
 
Kindersicherung
Du entscheidest, welche Musik, Videos und Apps auf dem iPod touch für deine Kinder geeignet sind.
Der iPod touch hat auch die folgenden praktischen Apps:
 
Kalender
Das Programm ""Kalender"" funktioniert mit Yahoo!, Google, Microsoft Outlook, iCal, MobileMe und Microsoft Exchange ActiveSync für Unternehmen. Füge Termine hinzu, lass dich an Termine erinnern, und abonniere Kalender, damit du über Feiertage und Sportveranstaltungen auf dem Laufenden bleibst.
 
Kontakte
Namen, E-Mail-Adressen, Telefonnummern und mehr - immer zur Hand. Synchronisier Kontakte in iTunes auf dem Mac oder PC mit dem iPod touch. Neue Kontakte kannst du auch unterwegs mit einem einfachen Fingertipp hinzufügen.
 
Notizen
Schluss mit Papier und Bleistift. Mach dir mit ""Notizen"" auf dem iPod schnell eine Notiz, damit du wichtige Infos immer parat hast. Maile deine Gedanken mit der integrierten Mail-Funktion an dich oder andere.
 
Aktien
Die Aktien App auf dem iPod touch zeigt dir Börseninformationen für die Aktien, die dich interessieren. Wenn du nähere Details über eine Aktie brauchst, tipp auf ""Y!"", um im Handumdrehen Yahoo! Finance zu öffnen.
 
Wetter
Informier dich über das Wetter in der ganzen Welt oder zuhause. Füge die gewünschten Städte hinzu und zeige eine sechstägige Vorhersage für alle an. Tipp auf ""Y!"", um den Yahoo! Stadtführer zu öffnen, der dir zeigt, wo was los ist.
 
Rechner
Im Programm ""Rechner"" des iPod touch stecken gleich zwei Rechner. Im Hochformat kannst du ihn als einfachen Taschenrechner verwenden. Dreh den iPod touch ins Querformat, um aus ihm einen wissenschaftlichen Rechner zu machen.
 
iPod touch Technologie
Dank der revolutionären Hardwaretechnologie im iPod touch kannst du alle Funktionen mit Streichen, Tippen und Auf- oder Zuziehen steuern. Deswegen wirkt das Autorennen so echt. Deswegen kannst du das, was du eben im Café mitbekommen hast, sofort twittern. Und genau deswegen ist der iPod touch der beste iPod aller Zeiten.
 
Multi-Touch
Das Multi-Touch-Display besitzt einen Schutzfilm über der kapazitiven Sensorik, die Berührungen anhand elektrischer Felder erkennt. Diese Informationen werden an das darunterliegende LCD-Display übertragen. Dank der Software des iPod touch kannst du mit Cover Flow durch Alben stöbern, durch deine Fotos blättern, mit Auf- und Zuziehen Bildausschnitte von Websites zoomen und Spiele superpräzise steuern.
 
Beschleunigungssensor
Der iPod touch reagiert über einen integrierten Beschleunigungssensor auf Bewegungen. Dieser Sensor erkennt, wenn du deinen iPod touch ins Querformat drehst und verändert automatisch den Inhalt des Displays. Die Technologie des Beschleunigungssensors kommt besonders bei Spielen gut, denn damit bist du mitten im Spielgeschehen. Das ist perfekt für Autorennen, bei denen der ganze iPod zum Lenkrad wird, und Geschicklichkeitsspiele wie Rolando, bei denen du das Spiel mit deinen Bewegungen steuerst
 
Drahtlos
Der iPod touch hat eine integrierte Unterstützung für drahtlosen 802.11b/g Internetzugriff. Überall, wo es ein Wi-Fi-Netzwerk gibt, kommst du mit deinem iPod touch ins Internet. Im Café mailen. Am Flughafen im Web surfen. Spiele vom Sofa aus kaufen. Im iTunes Store stöbern und Musik kaufen und laden. Der iPod touch findet nahegelegene Wi-Fi-Hot-Spots, auch geschützte Netzwerke. Wenn du ein bestimmtes Netzwerk bisher noch nicht verwendet hast, Drahtlos Symbol musst du beim ersten Mal ein Kennwort eingeben, das sich der iPod touch dann merkt. Wenn du dann das nächste Mal in Reichweite dieses Netzwerks bist, loggt er sich automatisch ein.
 
Bluetooth
Bluetooth ist eine drahtlose Technologie, mit der du Geräte ohne lästige Kabel verwenden kannst. Was bedeutet das für den iPod touch? Du kannst jetzt mit dem iPod touch und Bluetooth Kopfhörern Musik hören, ganz egal, wo im Raum der iPod ist. Du kannst also auf dem Bett relaxen, während der iPod auf dem Schreibtisch aufgeladen wird. Bluetooth auf dem iPod touch eignet sich auch besonders für Peer-to-Peer-Spiele.
 
Design
Der iPod touch ist von außen genau so großartig wie von innen. Du brauchst nur einen in die Hand zu nehmen. Das Gehäuse des iPod touch ist gerade einmal 8,5 mm hoch. Das optische Glas auf der Vorderseite und die Rückseite aus poliertem Edelstahl geben ihm einen eleganten Touch und fühlen sich in der Hand einfach gut an. Schalte ihn ein und du wirst über das brillante 3,5"" Display einfach staunen. Der iPod touch ist die perfekte Kombination aus großartigem Design und revolutionärer Technologie - das perfekte Paket.
";2;False;0;;;Apple iPod Touch 8 GB schwarz mit integrierter WiFi Funktion;apple-ipod-touch-8-gb-schwarz-2;True;True;PD-01085;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;169.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40871,5555092593;44;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000434-apple-ipod-touch-64-gb-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000435-apple-ipod-touch-64-gb-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000436-apple-ipod-touch-64-gb-schwarz.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Samsung Galaxy S II (i9100) DualCore Smartphone schwarz;"Samsung Galaxy S II (i9100) DualCore Smartphone (10.9 cm (4.3 Zoll) Super-Amoled Plus Display, Android 2.3, 8 MP Full-HD Kamera, 2 MP Frontkamera) schwarz ";"
Samsung launcht mit dem Galaxy S II den Nachfolger des Bestsellers Galaxy S. Das Galaxy S II ist nicht nur das schlankste (8,49 mm), sondern dank des 1,2 GHz Dual-Core Prozessors auch das schnellste Smartphone seiner Klasse. Darüber hinaus besticht es durch ein 4,3"" Super Amoled Plus Touch-Display. Das Galaxy S II verwendet als Betriebssystem die aktuellste Android 2.3 Version – auch bekannt unter dem Namen Gingerbread. Die integrierte 8 Megapixel Kamera mit LED Blitz hält die schönsten Momente in erstklassiger Qualität fest – darüber hinaus ermöglicht die 2 Megapixel Frontkamera Video Telefonate in beeindruckender Qualität. Das Schreiben von E-Mails und SMS gelingt unkompliziert dank Swype®-Texteingabe. Zahlreiche aktuelle und nützliche Apps stehen im Android Market™ zum Download bereit. Die integrierte Google Maps Navigation™ führt ans gewünschte Ziel. AllShare, HD Video, Exchange ActiveSync und eine Vielzahl an weiteren Applikationen lassen keine Wünsche offen. Ein erstklassiges Zusammenspiel von Hardware und Funktionen leistet sein Übriges für ein ausgezeichnetes Nutzererlebnis auf höchstem Niveau!
 
4,27-Zoll SUPER AMOLED Plus
Bekennen Sie Farbe! Dieses brillante Display bietet den besten Farbumfang, ein hohes Kontrastverhältnis sowie ultimative Schärfe bei Bildern. Die bahnbrechende Verkürzung der Video-Reaktionszeit sorgt für ruckfreie Videowiedergabe. Die neue Technologie benötigt weniger Platz und Energie: Im Vergleich zum Vorgänger benötigt das Display 18% weniger Energie. Es ist damit eines der dünnsten, langlebigsten Smartphones am Markt.
 
Brillante Performance
Das Unmögliche ist möglich. Der Samsung Dual Core Application Prozessor ist die reaktionsschnelle Antwort im Bereich mobile Performance. Er bietet Multitasking in Hochgeschwindigkeit, schnelles Laden von Internetseiten, schnelle Reaktionszeiten, eine intuitive Benutzeroberfläche, blitzschnelle Bildbearbeitung und Spiele mit hoher Performance. Und mit der superschnellen Möglichkeit zum Encodieren und Decodieren, die alles im Bereich Videoaufzeichnung und -wiedergabe (1080p / 30fps) unterstützt, stellt er alle anderen Dual Core-Prozessoren in den Schatten. Problemloses Video- oder Musik-Streaming bekommt dank des schnellen Drahtlosstandards HSPA 21 Mbps einen großen Schub. Hervorragende Rechenleistung, herausstechende Performance.
 
Schlankes Design
Schlank, schlanker, GALAXY S II. Das Samsung GALAXY S II führt die Riege an – mit nur 8,49 mm und einem luxuriösen Design liegt es zudem gut in der Hand. Das GALAXY S II ist eines der schlanksten Smartphones und bietet außerdem HyperSkin für einen schönen Metall-Look mit einer fingerabdruckfreien und rutschfesten Akkuabdeckung.
 
Readers Hub
Lassen Sie Ihre Bücher zu Hause: Das Samsung GALAXY S II übernimmt diese Aufgabe. Stöbern Sie im Readers Hub in Ihrer Bücherei mit Klassikern oder suchen Sie in mehr als 2 Millionen Büchern die neusten Bestseller. Sie können auch 2.500 Magazine in 20 Sprachen und 1.600 Zeitungen in 47 Sprachen zur Lieferung einrichten. Mit klarem, deutlichem Text und der hohen Bedienerfreundlichkeit macht das Lesen Spaß: vergrößern, nur Text und Seitenansichten, Audiozugriff sowie schnelles Verteilen per E-Mail sind nur einige Funktionen. Glauben Sie an Bücher, beschränken Sie sich jedoch nicht nur auf Papier.
 
8-Megapixel-Kamera mit LED-Blitz
Immer gute Fotos. Der 8-Megapixel-Kamera mit Autofokus entgehen auch bei Action-Fotos keine Details. Machen Sie auch bei schlechten Lichtverhältnissen mit dem integrierten LED-Blitz wunderschöne und detaillierte Aufnahmen. Und dank der stark verbesserten Benutzeroberfläche von Android Gingerbread ist selbst schneller Szenenwechsel möglich. Wechseln Sie problemlos auf die 2-Megapixel-Kamera vorne, um Selbstporträts zu machen. Einfach immer gute Bilder.
 
Aufzeichnung & Wiedergabe in Full-HD
Werden Sie zum Star. Mit den Möglichkeiten zur Videoaufzeichnung des Samsung GALAXY S II können auch Sie zur Berühmtheit werden. Mit der 1080p Full-HD-Aufzeichnung ist jeder Moment ein potenzielles Meisterwerk in der Entstehung. Erfassen Sie die Action in hoher Auflösung und mit Dual Core-Geschwindigkeit und geben Sie Ihre HD-Aufzeichnungen mit bestechender Klarheit auf dem 4,3"" SUPER AMOLED Plus Display wieder.
 
Spracherkennung & Sprachübersetzung
Einfach Sprachbefehle nutzen. Tippen Sie nur doppelt auf die Home-Taste und steuern Sie das Samsung GALAXY S II mit ausgewählten Sprachbefehlen. Führen Sie wichtige Funktionen wie anrufen, Musik hören oder SMS schreiben mit einfachen Sprachbefehlen aus. Sie können auch Ihre Gedanken festhalten, sich selbst eine Notiz schreiben oder unterwegs sogar mit Google Voice Translation eine Übersetzung anfertigen. Galaxy S II kann Ihnen eingehende Nachrichten auch vorlesen.
 
Game Hub
Noch mehr Spielspaß. Über den Game Hub von Samsung GALAXY S II können Sie hochwertige Spiele herunterladen: 12 soziale Netzwerkspiele und 13 Prämiumspiele einschließlich Gameloft’s Let Golf 2 und Real Football 2011. Sie können nach Spielen und Informationen zu Neuerscheinungen suchen oder einfach nur spielen. Mit einem Beschleunigungsaufnehmer, einem magnetischen Sensor und Gyroskop-Sensor heben sich Spiele mit Hand- und Armbewegungen deutlich aus der Masse ab. Die kleinste Bewegung reicht bereits aus – das ist spannende Unterhaltung.
 
Social Hub
Mit dem Social Hub lassen sich Ihre Online-Kontakte besser organisieren und synchronisieren. Sammeln Sie Ihre Informationen aus E-Mails, SMS, IM und SNS in einem einheitlichen Posteingang – Interaktionen mit anderen sind so schneller und auf die von Ihnen gewünschte Art möglich.
 
Music Hub
Musik darf nicht fehlen. Der neue native Music-Player von Samsung bietet ein intuitives Wiedergabesystem zum Suchen, Entdecken, Anspielen, Kaufen und Herunterladen von Musikstücken für unterwegs. Die App bietet auch viele Informationen zum Kauf sowie Zugriff auf alle gewünschten Künstler, Liedtexte und Bewertungen. Sie können Empfehlungen für neue Songs abrufen und durch Bassverstärkung und 5.1 Kanal-Sound den Hörspaß noch mehr steigern.
 
Microsoft Exchange ActiveSync
Das Samsung GALAXY S II ist für sicheren Zugriff auf Unternehmensressourcen auf einem Microsoft Exchange Server optimiert, damit Sie in Bezug auf geschäftliche E-Mails, Terminplaner, Kontakte und Aufgabensynchronisation auf dem Laufenden sind. Das Handy bietet die umfangreichste mobile Implementierung von Exchange ActiveSync. Es bietet das sicherste Mobile Device Management unter den Smartphones und unterstützt die meisten Richtlinien und Einschränkungen unter den Android ActiveSync Clients und ermöglicht Kommunikation in Echtzeit mit Telefonen der Mitarbeiter, um Einstellungen per Fernzugriff zu konfigurieren, die Einhaltung der Richtlinien zu überwachen, die Sicherheit bei synchronisierten Daten zu gewährleisten und verwaltete Telefone zu sperren oder Daten zu löschen.
";2;False;0;;;Samsung Galaxy S II (i9100) DualCore Smartphone schwarz;samsung-galaxy-s-ii-i9100-dualcore-smartphone-schwarz;True;True;PD-01084;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;439.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40871,5057638889;76;5;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000172-samsung-galaxy-s-ii-i9100-dualcore-smartphone-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000173-samsung-galaxy-s-ii-i9100-dualcore-smartphone-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000174-samsung-galaxy-s-ii-i9100-dualcore-smartphone-schwarz.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Nokia N9 Smartphone schwarz;"Nokia N9 Smartphone (9,9 cm (3,9 Zoll) Display, 16GB, Touchscreen, 8 Megapixel Kamera) schwarz ";"
Nokia N9 Smartphone
Formatfüllender Touchscreen
Ein einzigartiges Smartphone mit formatfüllendem Touchscreen. Die gewölbte Oberfläche aus kratzfestem Glas geht nahtlos in das glatte, aus einem Block gefertigte Gehäuse über. Jedes Detail strahlt Innovation aus. Auf dem brillanten AMOLED-Touchscreen erscheint alles in lebendigen Farben und das gewölbte Glas macht den Wechsel zwischen Apps per Fingerbewegung zum Kinderspiel.
 
Einfach nur eine Fingerbewegung - Überzeugend benutzerfreundlich
Alles läuft auf eine einfache Fingerbewegung hinaus. Das macht die Nutzung dieses Smartphones so intuitiv wie nie zuvor. Es gibt keine Zurück- oder Menü-Taste mehr – nur fliessende Fingerbewegungen, während Sie von App zu App wechseln. Mit einer Fingerbewegung über eine beliebige Ecke des Touchscreens gelangen Sie zur Startansicht, mit einer weiteren Bewegung wechseln Sie zwischen den drei Startansichten.
 
Eine Startansicht - Drei einfache Ansichten
Drei Ansichten sind alles, was Sie brauchen. In der vertrauten App-Ansicht starten Sie Anwendungen, eine weitere Ansicht zeigt die offenen Apps und macht Multitasking zum Kinderspiel: Sie machen genau dort weiter, wo Sie aufgehört haben.- Die Ansicht ""Ereignisse"" bringt Sie jederzeit auf den neuesten Stand der Dinge. Live-Feeds von Facebook und Twitter, E-Mails in Echtzeit, RSS-Feeds und mehr – alles an einer Stelle.
 
Karten und Navigation kostenlos
Live-Feeds von Facebook und Twitter, E-Mails in Echtzeit, RSS-Feeds und mehr – alles an einer Stelle. Sie finden die besten Angebote in Ihrer Stadt wie Cafés, Geschäfte, Konzerte, Hotels und mehr. Für mehr als 80 Städte weltweit steht Ihnen eine Übersicht von Strecken und Haltestellen des öffentlichen Nahverkehrs zur Verfügung. Entsprechendes Kartenmaterial ist bereits vorinstalliert, sodass Sie sofort starten können. Die Anwendung ""Fahren"" ist dank einfacher Bedienung über Touchscreen für die Verwendung im Auto optimiert.
 
Browser der nächsten Generation
Zeit für mehr Tempo. Das Nokia N9 bietet einen schnellen mobilen Internet-Browser und Seiten werden in kürzester Zeit aufgebaut. Die Unterstützung für HTML5 bedeutet für Sie das Beste aus dem Web, inklusive interaktiver Apps und schneller Videowiedergabe. Der Browser reagiert schnell auf jede Berührung. Sie können mehrere Seiten gleichzeitig öffnen und schnell zwischen den Seiten wechseln.
 
 
 
8-Megapixel-Kamera mit Optik von Carl Zeiss
Die Gelegenheit für ein gutes Foto kommt schnell und ist ebenso schnell vorbei. Mit der integrierten 8-Megapixel-Kamera mit Optik von Carl Zeiss können Sie brillante Fotos oder Videos in herausragender HD-Qualität aufnehmen.
 
Die besten Apps und Spiele
Apps sind heutzutage allgegenwärtig. Das Wichtigste ist jedoch die Qualität und nicht, wie viele man besitzt. Auf dem Nokia N9 sind die besten Apps wie Skype, Facebook, Twitter, AccuWeather und AP Mobile bereits vorinstalliert. Auch die Vollversion von Angry Birds ist bereits vorinstalliert – für viele Stunden Spass. Und im Ovi Store gibt es viele weitere Apps und Spiele.
";2;False;0;;;Nokia N9 Smartphone schwarz;nokia-n9-smartphone-schwarz;True;True;PD-01083;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;539.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40871,4967013889;74;17;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000164-nokia-n9-smartphone-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000165-nokia-n9-smartphone-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000166-nokia-n9-smartphone-schwarz.jpg;3;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Nokia N9 Smartphone magenta;Nokia N9 Smartphone (9,9 cm (3,9 Zoll) Display, 16GB, Touchscreen, 8 Megapixel Kamera) magenta;"
Nokia N9 Smartphone
Formatfüllender Touchscreen
Ein einzigartiges Smartphone mit formatfüllendem Touchscreen. Die gewölbte Oberfläche aus kratzfestem Glas geht nahtlos in das glatte, aus einem Block gefertigte Gehäuse über. Jedes Detail strahlt Innovation aus. Auf dem brillanten AMOLED-Touchscreen erscheint alles in lebendigen Farben und das gewölbte Glas macht den Wechsel zwischen Apps per Fingerbewegung zum Kinderspiel.
 
Einfach nur eine Fingerbewegung - Überzeugend benutzerfreundlich
Alles läuft auf eine einfache Fingerbewegung hinaus. Das macht die Nutzung dieses Smartphones so intuitiv wie nie zuvor. Es gibt keine Zurück- oder Menü-Taste mehr – nur fliessende Fingerbewegungen, während Sie von App zu App wechseln. Mit einer Fingerbewegung über eine beliebige Ecke des Touchscreens gelangen Sie zur Startansicht, mit einer weiteren Bewegung wechseln Sie zwischen den drei Startansichten.
 
Eine Startansicht - Drei einfache Ansichten
Drei Ansichten sind alles, was Sie brauchen. In der vertrauten App-Ansicht starten Sie Anwendungen, eine weitere Ansicht zeigt die offenen Apps und macht Multitasking zum Kinderspiel: Sie machen genau dort weiter, wo Sie aufgehört haben.- Die Ansicht ""Ereignisse"" bringt Sie jederzeit auf den neuesten Stand der Dinge. Live-Feeds von Facebook und Twitter, E-Mails in Echtzeit, RSS-Feeds und mehr – alles an einer Stelle.
 
Karten und Navigation kostenlos
Live-Feeds von Facebook und Twitter, E-Mails in Echtzeit, RSS-Feeds und mehr – alles an einer Stelle. Sie finden die besten Angebote in Ihrer Stadt wie Cafés, Geschäfte, Konzerte, Hotels und mehr. Für mehr als 80 Städte weltweit steht Ihnen eine Übersicht von Strecken und Haltestellen des öffentlichen Nahverkehrs zur Verfügung. Entsprechendes Kartenmaterial ist bereits vorinstalliert, sodass Sie sofort starten können. Die Anwendung ""Fahren"" ist dank einfacher Bedienung über Touchscreen für die Verwendung im Auto optimiert.
 
Browser der nächsten Generation
Zeit für mehr Tempo. Das Nokia N9 bietet einen schnellen mobilen Internet-Browser und Seiten werden in kürzester Zeit aufgebaut. Die Unterstützung für HTML5 bedeutet für Sie das Beste aus dem Web, inklusive interaktiver Apps und schneller Videowiedergabe. Der Browser reagiert schnell auf jede Berührung. Sie können mehrere Seiten gleichzeitig öffnen und schnell zwischen den Seiten wechseln.
 
 
 
8-Megapixel-Kamera mit Optik von Carl Zeiss
Die Gelegenheit für ein gutes Foto kommt schnell und ist ebenso schnell vorbei. Mit der integrierten 8-Megapixel-Kamera mit Optik von Carl Zeiss können Sie brillante Fotos oder Videos in herausragender HD-Qualität aufnehmen.
 
Die besten Apps und Spiele
Apps sind heutzutage allgegenwärtig. Das Wichtigste ist jedoch die Qualität und nicht, wie viele man besitzt. Auf dem Nokia N9 sind die besten Apps wie Skype, Facebook, Twitter, AccuWeather und AP Mobile bereits vorinstalliert. Auch die Vollversion von Angry Birds ist bereits vorinstalliert – für viele Stunden Spass. Und im Ovi Store gibt es viele weitere Apps und Spiele.
";2;False;0;;;Nokia N9 Smartphone magenta;nokia-n9-smartphone-magenta;True;True;PD-01082;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;549.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40871,4934027778;"74;2095";17;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000655-nokia-n9-smartphone-magenta.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000656-nokia-n9-smartphone-magenta.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000657-nokia-n9-smartphone-magenta.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Apple iPhone 4S weiß ";Apple iPhone 4S weiß;"
Das neue iPhone 4S - jetzt mit Dual Core A5 Chip, neuer 8 MegaPixel-Kamera, iOS 5 und iCloud sowie dem neuen Siri.
 
Dual-Core A5 Chip. Der leistungsstärkste iPhone Prozessor aller Zeiten.
Mit zwei Prozessorkernen liefert der A5 Chip bis zu 2x mehr Leistung und bis zu 7x schnellere Grafik. Das wirst du merken. Und zwar schnell. Das iPhone 4S reagiert extrem schnell, was du sofort merkst, wenn du Apps öffnest, im Web surfst, beim Spielen und auch bei allem anderen. Und ganz egal was du machst, du kannst es richtig lange machen. Denn der A5 Chip ist so effizient, dass das iPhone 4S eine enorm lange Batterielaufzeit hat.
 
Die Kaum-zu-glauben-dass-es-ein-Handy-ist Kamera.
Wahrscheinlich die beste Kamera, die es je auf einem Telefon gab. Und dank fortschrittlichster Optik ist sie wahrscheinlich auch die einzige Kamera, die du brauchst. Schließlich hat sie eine Auflösung von 8 Megapixeln und eine spezielle Linse mit einer größeren f/2,4 Blende. Außerdem bietet sie einen optimierten rückwärtig belichteten Sensor, exzellenten Weißabgleich, verbesserte Farbgenauigkeit, Gesichtserkennung und reduzierte Bewegungsunschärfe. Es ist also ganz egal, wie viele Leute, wie viel Licht und wie viel Action du aufnimmst – alles sieht genau so aus, wie es aussehen soll. Und warte erst, bis du die Fotos siehst.
 
Siri. Dein intelligenter, hilfsbereiter Assistent.Du musst ihn nur fragen.
Jetzt kannst du dein iPhone einfach mit deiner Stimme benutzen. Sprich mit Siri so, wie du mit einer Person sprichst und sag ""Erinnere mich daran, Mama anzurufen, wenn ich zu Hause bin"" oder ""Brauche ich einen Schirm?"". Siri spricht Deutsch und versteht nicht nur, was du sagst, sondern auch was du meinst. Es erkennt, welche Apps für die richtige Antwort nötig sind. Und antwortet dir dann – wie dein persönlicher Assistent. Siri telefoniert, sendet Nachrichten, plant Meetings, legt Erinnerungen fest und mehr. Was noch? Frag einfach, und Siri sagt es dir selbst.
 
Videoaufnahmen. In fantastischem 1080p HD.
Nimm fantastische 1080p HD Videos auf, wo immer du bist. Durch die neue fortschrittliche Optik der Kamera ist das Licht immer genau richtig, die Farben immer leuchtend und alles sieht noch besser aus, als du es in Erinnerung hattest. Die Bildstabilisierung gleicht verwackelte Aufnahmen aus. Und du kannst Videos direkt auf dem iPhone bearbeiten und so schnell mit anderen teilen, wie du sie aufnimmst.
 
iOS. Das fortschrittlichste mobile Betriebssystem der Welt. Und auch das einfachste.
Jede neue iOS Version bietet Möglichkeiten, die alles noch einfacher machen. Deshalb ist iOS allen anderen um Jahre voraus. Und iOS 5 geht wieder einen großen Schritt weiter und bringt mehr als 200 neue Features auf das iPhone 4S. Hier sind nur einige unserer Favoriten.
 
iCloud. Deine Inhalte. Auf all deinen Geräten.
Mit iCloud kannst du deine Inhalte ganz einfach verwalten, denn iCloud erledigt alles für dich. iCloud speichert deine Musik, Fotos, Apps, Mails, Kontakte, Kalender, Dokumente und mehr und pusht alles drahtlos an all deine Geräte. Automatisch, nahtlos und einfach so.
 
Retina Display.Das ist ganz klar.
Auf dem iPhone 4S siehst du einfach alles gestochen scharf und lebendig. Das Retina Display ist das höchstauflösende Telefondisplay aller Zeiten. Die Pixeldichte ist so hoch, dass das menschliche Auge keine einzelnen Pixel erkennen kann. Was du aber ganz bestimmt siehst, sind gestochen scharfe Texte, Grafiken und Bilder. Alles sieht sogar noch besser aus als gedruckt.
 
FaceTime. Wink doch mal hallo.
Mit FaceTime hörst du nicht nur eine Stimme, sondern siehst auch das Gesicht dazu – von iPhone zu iPhone, iPad 2, iPod touch oder Mac über Wi-Fi. Es ist also ganz egal, wo die anderen sind und wo du bist – du bist immer da. FaceTime Anrufe sind so einfach wie ganz normale Anrufe. Und mit Siri sind sie sogar noch einfacher. Sag Siri einfach, dass du mit deiner Mutter facetimen willst, und schon seht ihr euch. Einfach so. Du verpasst nie wieder ein wichtiges Ereignis, Meeting oder einen guten Lacher. Und wer würde sich nicht darüber freuen, dich zu sehen?
 
AirPlay. Live vom iPhone auf deinen Fernseher.
Mit AirPlay kannst du Inhalte von deinem iPhone via Apple TV drahtlos an deinen HD Fernseher und Lautsprecher streamen.6 Und mit der AirPlay Synchronisierung erscheint alles, was du auf deinem iPhone siehst oder machst, gleichzeitig auf deinem HD Fernseher.
 
AirPrint.Alles drahtlos drucken.
Drucke deine Mails, Fotos, Webseiten und Dokumente einfach über Wi-Fi von deinem iPhone aus.7 Ganz ohne Software zu laden, Treiber zu installieren oder Kabel anzuschließen. Nur ein paar Fingertipps und schon hast du das, was eben noch auf dem iPhone war, als Ausdruck in der Hand.
 
Besser. Schneller. Weltweiter.
Das iPhone 4S ist das erste Telefon, das zum Übertragen und Empfangen intelligent zwischen zwei Antennen wechselt. So ist die Anrufqualität deutlich besser. Außerdem verdoppeln die Antennen die maximale HSDPA Datengeschwindigkeit auf 14,4 Mbit/s.8 Und das bedeutet schnellere Verbindungen, schnelleres Laden und Neuladen und schnellere Downloads. Das iPhone 4S ist ein Telefon für die ganze Welt. Du kannst es also fast überall verwenden. Ob GSM- oder CDMA-Standard spielt keine Rolle. Nutze es via Roaming in GSM-Netzen in 200 Ländern weltweit.
 
Integrierte Apps. Machen alles, damit du alles machen kannst.
Ganz Alltägliches erledigst du mit dem iPhone 4S auf ganz außergewöhnliche Weise. Mach fantastische Fotos und nimm HD Videos auf. Sieh Freunde und Familie mit FaceTime. Tauche auf dem Retina Display richtig ins Web ein. Check deine Mails. Sende Nachrichten. Lege Erinnerungen fest. Schau in deinen Kalender. Oder sag Siri einfach, wie es dir helfen soll. Siri findet dann selbst heraus, welche Apps es verwenden muss.
 
Aufgrund der sehr umfangreichen Leistungsmerkmale können wir Ihnen hier nur einen Auszug präsentieren. Die vollständigen Funktionsbeschreibungen inkl. einer Vielzahl von Videos entnehmen Sie bitte der Herstellerwebseite.
•Apple iPhone 4S
•115,2 x 58,6 x 9,3 mm klein und 140 g leicht
•Kapazität: 16 GB Flash-Laufwerk
•Kamera, Fotos und Video:
• 8.0 Megapixel Kamera
• Videoaufnahme, HD (1080p) bis zu 30 fps mit Audio
• Fotos und Videos in VGA-Qualität mit bis zu 30 fps mit der Kamera an der Vorderseite
• Fokussieren per Fingertipp für Videos und Fotos LED-Blitz
• Geotagging für Fotos und Videos
•Display:
• Retina Display
• 3,5""-Multitouch-Display (8,89 cm Diagonale)
• Auflösung von 960 x 640 Pixeln mit 326ppi
• Typisches Kontrastverhältnis: 800:1
• Fettabweisende Beschichtung an der Vorder- und Rückseite
• Unterstützung für die Anzeige mehrerer Sprachen und Zeichen gleichzeitig
•Stromversorgung und Batterie:
• Sprechdauer: bis zu 8 Std. mit 3G, bis zu 14 Std. mit 2G
• Standbydauer: bis zu 200 Std.
• Internetnutzung: bis zu 6 Std. mit 3G, bis zu 9 Std. mit Wi-Fi
• Videowiedergabe: bis zu 10 Std., Audiowiedergabe: bis zu 40 Std.
•Betriebssystem: iOS 5
•Mobilfunknetz und Wi-Fi:
• UMTS/HSDPA/HSUPA (850, 900, 1900, 2100 MHz)
• GSM/Edge (850, 900, 1800, 1900 MHz)
• Funktechnologie: 802,11b/g/n Wi-Fi (802.11 nur mit 2,4 GHz), Bluetooth 4.0
•GPS: Assisted GPS
•Digitaler Kompass
•Unterstützte Audioformate: AAC (8 bis 320 KBit/Sek.), Protected AAC (aus dem iTunes Store), HE-AAC, MP3 (8 bis 320 KBit/Sek.), MP3 VBR, Audible (Formate 2, 3, 4, Audible Enhanced Audio, AAX und AAX+), Apple Lossless, AIFF und WAV
•TV und Video: AirPlay Mirroring to Apple TV support at 720p, Video mirroring and video out support: Up to 1080p with Apple Digital AV Adapter or Apple VGA Adapter (adapters sold separately), Video out support at 576p and 480p with Apple Component AV Cable; 576i and 480i with Apple Composite AV Cable (cables sold separately)
•Unterstützte Videoformate: H.264 Video: bis zu 720p, 30 Bilder pro Sekunde, Main Level Profile Level 3.1 mit AAC-LC Audio bis zu 160 KBit/Sek., 48 kHz, Stereo-Audio in den Formaten .m4v, .mp4 und .mov; MPEG.4 Video: bis zu 2,5 MBit/Sek., 640 x 480 Pixel, 30 Bilder pro Sekunde, Simple Profile mit AAC-LC Audio bis zu 160 KBit/Sek., 48 kHz, Stereo-Audio in den Formaten .m4v, .mp4 und .mov; Motion JPEG (M-JPEG): bis zu 35 MBit/Sek., 1280 x 720 Pixel, 30 Bilder pro Sekunde, Audio im Format ulaw, PCM Stereo-Audio im Format .avi
•Sensoren:
• 3-Achsen-Gyrosensor
• Beschleunigungssensor
• Annäherungssensor
• Umgebungslichtsensor
 
Lieferumfang:
iPhone 4S, Apple Earphones mit Fernbedienung und Mikrofon, Dock Connector-auf-USB-Kabel, Dokumentation
";2;False;0;;;Apple iPhone 4S weiß;apple-iphone-4s-weiss;True;True;PD-01080;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,5000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;779.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40870,6516782407;71;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000646-apple-iphone-4s-weis.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000647-apple-iphone-4s-weis.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000648-apple-iphone-4s-weis.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"AVM FRITZ!Fon MT-F VoIP Dect-Telefon ";"AVM FRITZ!Fon MT-F Innovatives DECT-Telefon ";"
FRITZ!Fon MT-F: HD-Telefonie und komfortable Internetdienste mit DECT.
Telefonieren Sie mit dem Schnurlostelefon FRITZ!Fon MT-F in bestechender Qualität über das Internet und nutzen Sie komfortable Webdienste. Als intelligentes Telefon der neuesten DECT-Generation vereint das FRITZ!Fon den Komfort der schnurlosen Telefonie mit den Qualitäts- und Leistungsmerkmalen der Internettelefonie (VoIP) in einem Gerät.
 
Bei der Internettelefonie mit einem FRITZ!Fon wird durch HD-Telefonie (High Definition) ein brillantes, natürliches Klanggefühl erreicht. Sprache lässt sich mit dem FRITZ!Fon in ihrem gesamten Frequenzspektrum wiedergeben, was die Klangqualität von Festnetzverbindungen deutlich übertrifft.
 
FRITZ!Fon unterstützt die übertragung großer Bandbreiten. Dies ermöglicht neben HD-Telefonie auch die Nutzung komfortabler Internetdienste wie den Empfang von E-Mails, Podcasts, RSS-Feeds und Internetradio.
 
Die Steuerung von FRITZ!Box-Anwendungen am Handgerät bietet viel zusätzlichen Komfort. Und durch DECT-Eco wird Funkabstrahlung bei Nichtnutzung der Telefone verhindert.
 
Die FRITZ!Box-Modelle FRITZ!Box Fon WLAN 7390, 7320, 7270, 7240 sowie FRITZ!Box 6360 Cable stellen mit der integrierten DECT-Basisstation, mehreren Anrufbeantwortern und Telefonbüchern für bis zu 300 Einträge den idealen Partner für das FRITZ!Fon dar. Mit der umfangreichen Prozessor- und Speicherausstattung ist auch der Grundstein für neue Anwendungen gelegt. Denn das FRITZ!Fon ist lernfähig:
 
Als eines der ersten intelligenten Schnurlostelefone wird es auch künftig per Firmware-Updates aktualisiert und um neue Funktionen erweitert werden können.
 
Umfangreicher Komfort
Das FRITZ!Fon MT-F ist mit zahlreichen Komfortfunktionen ausgestattet. Dazu zählen Lauthören und Freisprechen in HD-Qualität sowie ISDN-Leistungsmerkmale wie Namensanzeige bei bekannten Rufnummern, Halten, Makeln, Anklopfen, Rufumleitung oder Dreierkonferenz. Die Internettelefonie in HD-Qualität lässt sich so in ihrem vollen Umfang und Komfort nutzen, ohne dass der Computer eingeschaltet sein muss.
 
FRITZ!Fon informiert zudem aktiv über unbeantwortete Anrufe, Nachrichten auf dem Anrufbeantworter und zeigt eingegangene E-Mails an. An der DECT-Basisstation der FRITZ!Box Fon WLAN 7390, 7320, 7270, 7240 oder FRITZ!Box 6360 Cable lassen sich bis zu 6 FRITZ!Fon-Handgeräte oder andere DECT-Telefone anmelden. Die Erstinstallation und individuelle Einstellungen erfolgen dabei bequem über einfache Assistenten.
 
FRITZ!Box als idealer Partner
Das FRITZ!Fon MT-F kann als Mobilteil an jeder DECT-Basisstation eingesetzt werden. Im Zusammenspiel mit der FRITZ!Box Fon WLAN 7390, 7320, 7270, 7240 oder FRITZ!Box 6360 Cable kann jedoch das volle Spektrum der Möglichkeiten beim Telefonieren und Surfen über das Internet ausgenutzt werden.
 
Die FRITZ!Box Fon WLAN 7390 zum Beispiel vereint eine bisher nicht erreichte Vielfalt in einem Gerät: VDSL- und ADSL-Unterstützung, DECT-Basisstation fürs schnurlose Telefonieren sowie WLAN N für die optimale Datenübertragung. über den Mediaserver sind gespeicherte Filme, Musik und Bilder auch bei ausgeschaltetem Computer im gesamten Netzwerk verfügbar. Darüber hinaus kann der Online-Speicher wie eine lokale Festplatte genutzt werden. So wird die FRITZ!Box Fon WLAN 7390 zur idealen Plattform für vernetzte Anwendungen wie IPTV, Video on Demand oder Mediastreaming.
 
Bedienung
- Einfach einschalten und Suchtaste auf FRITZ!Box drücken.
 
- Einfache Bedienung über intuitives Menü.
 
- Telefonbuch komfortabel über FRITZ!Box-Oberfläche einrichten und anzeigen.
 
- In FRITZ!Box integrierte Anrufbeantworter einfach am FRITZ!Fon MT-F einrichten und abhören.
 
- Blinkende Leuchtdiode signalisiert eingegangene Anrufe, neue Nachrichten auf dem Anrufbeantworter und neue E-Mails.
";2;False;0;;;AVM FRITZ!Fon MT-F;avm-fritzfon-mt-f-voip-dect-telefon;True;True;PD-01079;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;79.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40653,4526388889;20;34;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000643-avm-fritzfon-mt-f-voip-dect-telefon.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000644-avm-fritzfon-mt-f-voip-dect-telefon.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000645-avm-fritzfon-mt-f-voip-dect-telefon.jpg;3;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Apple iPhone 4 weiß;Apple iPhone 4 weiß;"
Produktbeschreibungen
- Retina Display, 3,5"" Multi-Touch-Widescreen-Display (8,89 cm Diagonale)
- 960 x 640 Pixel bei 326 ppi
- Kontrastverhältnis: 800:1
- Fettabweisende Beschichtung an der Vorder- und Rückseite
- Unterstützung für die Anzeige mehrerer Sprachen und Zeichen gleichzeitig
- UMTS/HSDPA/HSUPA
- GSM/EDGE
- 802.11b/g/n WLAN
- Bluetooth 2.1 + EDR
- Li-Ionen-Akku, Sprechdauer bis zu 14Std. (2G), Internet bis zu 10Std. (WLAN)
 
";2;False;0;;;Apple iPhone 4 weiß;apple-iphone-4-weiss;True;True;PD-01078;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;779.0000;779.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.5000;0.0000;0.0000;0.0000;40653,4446064815;71;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000641-apple-iphone-4-weis.png;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000642-apple-iphone-4-weis.png;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Apple iPhone 4 schwarz ";"Apple iPhone 4 schwarz ";"
Produktbeschreibungen
- Retina Display, 3,5" Multi-Touch-Widescreen-Display (8,89 cm Diagonale)
- 960 x 640 Pixel bei 326 ppi
- Kontrastverhältnis: 800:1
- Fettabweisende Beschichtung an der Vorder- und Rückseite
- Unterstützung für die Anzeige mehrerer Sprachen und Zeichen gleichzeitig
- UMTS/HSDPA/HSUPA
- GSM/EDGE
- 802.11b/g/n WLAN
- Bluetooth 2.1 + EDR
- Li-Ionen-Akku, Sprechdauer bis zu 14Std. (2G), Internet bis zu 10Std. (WLAN)
";2;False;0;;;"Apple iPhone 4 schwarz ";apple-iphone-4-schwarz;True;True;PD-01077;;;False;0;False;;False;False;0;False;0;1;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;2;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;639.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40653,4410763889;71;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000639-apple-iphone-4-schwarz.png;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000640-apple-iphone-4-schwarz.png;;1;;False;ounce;;;;False;False;False;;;;;False;;;;;; +5;0;True;Apple iPad 2 schwarz;Apple iPad 2. Generation schwarz;"
Kapazität
16-GB-Flash-Laufwerk
32-GB-Flash-Laufwerk
64-GB-Flash-Laufwerk

Abmessungen und Gewicht

•Höhe: 241,2 mm
•Breite: 185,7 mm
•Tiefe: 8,8 mm
•Gewicht: 601 g

•Höhe: 241,2 mm
•Breite: 185,7 mm
•Tiefe: 8,8 mm
•Gewicht: 613 g


Drahtlose Technologie und Funknetz

•Wi-Fi (802.11a/b/g/n)
•Bluetooth 2.1 + EDR Technologie
•Wi-Fi + 3G Modell: UMTS/HSDPA/HSUPA (850, 900, 1900, 2100 MHz); GSM/EDGE (850, 900, 1800, 1900 MHz)
•Nur Datentransfer
•Wi-Fi (802.11a/b/g/n)
•Bluetooth 2.1 + EDR Technologie
Weitere Infos zu Wi-Fi + 3G

Display

•9,7"" Multi-Touch Hochglanz-Widescreendisplay mit LED-Hintergrundbeleuchtung und IPS-Technologie (24,63 cm Diagonale)
•Auflösung von 1024 x 768 Pixeln bei 132 ppi
•Fettabweisende Beschichtung
•Unterstützung für die Anzeige mehrerer Sprachen und Zeichen gleichzeitig
 
Chip
Speziell entwickelter, hochleistungsfähiger 1 GHz Dual-Core Apple A5 SOC (System-on-a-Chip) mit niedrigem Stromverbrauch
 
Kamera, Fotos, Videoaufnahme

•Rückkamera: Videoaufnahme, HD (720p) bis zu 30 fps mit Audio, Fotokamera mit 5-fach Digitalzoom
•Frontkamera: Videoaufnahme, VGA mit bis zu 30 fps mit Audio, Fotokamera in VGA-Qualität
•Fokussieren per Fingertipp für Videos und Fotos
•Geotagging für Fotos und Videos via Wi-Fi
 
Stromversorgung und Batterie

•Integrierte wiederaufladbare Lithium-Polymer-Batterie mit 25 Wattstunden
•Bis zu 10 Stunden Surfen im Web mit Wi-Fi, Video- oder Musikwiedergabe
•Aufladen über das Netzteil oder einen USB Anschluss am Computer

•Integrierte wiederaufladbare Lithium-Polymer-Batterie mit 25 Wattstunden
•Bis zu 10 Stunden Surfen im Web mit Wi-Fi, Video- oder Musikwiedergabe
•Bis zu 9 Stunden Batterielaufzeit beim Surfen im Internet über das 3G Datennetzwerk
•Aufladen über das Netzteil oder einen USB Anschluss am Computer
 
Ein- und Ausgabe

•30-poliger Dock-Anschluss
•3,5 mm Stereo-/Kopfhöreranschluss (Minianschluss)
•Integrierter Lautsprecher
•Mikrofon

•30-poliger Dock-Anschluss
•3,5 mm Stereo-/Kopfhöreranschluss (Minianschluss)
•Integrierter Lautsprecher
•Mikrofon
•Fach für Micro-SIM-Karte (nur beim Wi-Fi + 3G Modell)
 
Sensoren

•3-Achsen-Gyrosensor
•Beschleunigungssensor
•Umgebungslichtsensor

•3-Achsen-Gyrosensor
•Beschleunigungssensor
•Umgebungslichtsensor
 
Ortungsfunktion

•Wi-Fi
•Digitaler Kompass

•Wi-Fi
•Digitaler Kompass
•Assisted GPS
•Mobilfunknetz
 
Audiowiedergabe

•Frequenzbereich: 20 Hz bis 20.000 Hz
•Unterstützte Audioformate: HE-AAC (V1 und V2), AAC (8 bis 320 Kbit/s), Protected AAC (aus dem iTunes Store), MP3 (8 bis 320 Kbit/s), MP3 VBR, Audible (Formate 2, 3, 4, Audible Enhanced Audio, AAX und AAX+), Apple Lossless, AIFF und WAV
•Maximale Lautstärke vom Benutzer festlegbar
•Dolby Digital 5.1 Surround Sound Durchschleifen mit Apple Digital AV Adapter (separat erhältlich)
 
TV und Video

•Unterstützung für Bildschirmsynchronisation und Videoausgabe: bis zu 1080p mit dem Apple Digital AV Adapter oder dem Apple VGA-Adapter (Kabel separat erhältlich)
•Unterstützung für die Videoausgabe mit 576p und 480p mit dem Apple AV-Kabel (Komponentenvideo), mit 576i und 480i mit dem Apple AV-Kabel (Composite-Video)
•Unterstützte Videoformate: H.264 Video: bis zu 720p, 30 Bilder pro Sekunde, Main Profile Level 3.1 mit AAC-LC Audio mit bis zu 160 Kbit/s, 48 kHz, Stereo-Audio in den Formaten .m4v, .mp4 und .mov; MPEG-4 Video: bis zu 2,5 Mbit/s, 640 x 480 Pixel, 30 Bilder pro Sekunde, Simple Profile mit AAC-LC Audio mit bis zu 160 Kbit/s, 48 kHz, Stereo-Audio in den Formaten .m4v, .mp4 und .mov; Motion JPEG (M-JPEG): bis zu 35 Mbit/s, 1280 x 720 Pixel, 30 Bilder pro Sekunde, Audio im Format .ulaw, PCM Stereo-Audio im Format .avi
 
Unterstützte
E-Mail Anhänge

Anzeigbare Dokumenttypen: .jpg, .tiff, .gif (Bilder); .doc und .docx (Microsoft Word); .htm und .html (Webseiten); .key (Keynote); .numbers (Numbers); .pages (Pages); .pdf (Vorschau und Adobe Acrobat); .ppt und .pptx (Microsoft PowerPoint); .txt (Text); .rtf (Rich Text Format); .vcf (Kontaktdaten); .xls und .xlsx (Microsoft Excel)

Sprachen

•Sprachunterstützung für Englisch (USA), Englisch (Großbritannien), Französisch (Frankreich), Deutsch, traditionelles Chinesisch, vereinfachtes Chinesisch, Niederländisch, Italienisch, Spanisch, Portugiesisch (Brasilien), Portugiesisch (Portugal), Dänisch, Schwedisch, Finnisch, Norwegisch, Koreanisch, Japanisch, Russisch, Polnisch, Türkisch, Ukrainisch, Ungarisch, Arabisch, Thailändisch, Tschechisch, Griechisch, Hebräisch, Indonesisch, Malaiisch, Rumänisch, Slowakisch, Kroatisch, Katalanisch und Vietnamesisch

•Tastaturunterstützung für Englisch (USA), Englisch (Großbritannien), Französisch (Frankreich), Französisch (Kanada), Französisch (Schweiz), Deutsch, traditionelles Chinesisch (Handschrift, Pinyin, Zhuyin, Cangjie, Wubihua), vereinfachtes Chinesisch (Handschrift, Pinyin, Wubihua), Niederländisch, Italienisch, Spanisch, Portugiesisch (Brasilien), Portugiesisch (Portugal), Dänisch, Schwedisch, Finnisch, Norwegisch, Koreanisch, Japanisch (Romaji, 10 Tasten), Japanisch (Kana), Russisch, Polnisch, Türkisch, Ukrainisch, Estnisch, Ungarisch, Isländisch, Litauisch, Lettisch, Flämisch, Arabisch, Thailändisch, Tschechisch, Griechisch, Hebräisch, Indonesisch, Malaiisch, Rumänisch, Slowakisch, Kroatisch, Bulgarisch, Serbisch (Kyrillisch/Lateinisch), Katalanisch, Vietnamesisch, Tibetisch, Mazedonisch und Cherokee
 
•Wörterbuchunterstützung (aktiviert Textvorhersage und automatische Korrektur) für Englisch (USA), Englisch (Großbritannien), Französisch, Deutsch, traditionelles Chinesisch, vereinfachtes Chinesisch, Niederländisch, Italienisch, Spanisch, Portugiesisch (Brasilien), Portugiesisch (Portugal), Dänisch, Schwedisch, Finnisch, Norwegisch, Koreanisch, Japanisch (Romaji), Japanisch (Kana), Russisch, Polnisch, Türkisch, Ukrainisch, Ungarisch, Litauisch, Flämisch, Arabisch, Thailändisch, Tschechisch, Griechisch, Hebräisch, Indonesisch, Malaiisch, Rumänisch, Slowakisch, Kroatisch, Katalanisch, Vietnamesisch und Cherokee

Bedienungshilfen

•Unterstützung für die Wiedergabe von Inhalten mit erweiterten Untertiteln
•VoiceOver Bildschirmlesetechnologie
•Bildschirmfüllender Zoom
•Anzeigeoption ""Weiß-auf-Schwarz""
•Mono-Audioausgabe
 
Umgebungsbedingungen

•Betriebstemperatur: 0 °C bis 35 °C
•Lagertemperatur: -20 °C bis 45 °C
•Relative Luftfeuchtigkeit: 5 % bis 95 %, nicht kondensierend
•Maximale Betriebshöhe: ca. 3.000 m über NN, ohne Druckausgleich
 
Voraussetzungen für Mac

•Mac mit USB 2.0 Anschluss
•Mac OS X 10.5.8 (oder neuer)
•iTunes 10.2 oder neuer empfohlen
(kostenlos ladbar unter www.itunes.com/de/download)
•iTunes Store Account
•Internetzugang
 
Voraussetzungen für Windows

•PC mit USB 2.0 Anschluss
•Windows 7, Windows Vista oder Windows XP Home oder Professional mit Service Pack 3 (oder neuer)
•iTunes 10.2 oder neuer empfohlen
(kostenlos ladbar unter www.itunes.com/de/download)
•iTunes Store Account
•Internetzugang
 
Lieferumfang

•iPad
•Dock Connector auf USB Kabel
•10W USB Power Adapter (Netzteil)
•Dokumentation
 
Umweltverträglichkeit

 
Das iPad steht exemplarisch für das Engagement von Apple in Sachen Umweltschutz. Die folgenden Merkmale des iPad tragen zu seiner geringeren Umweltbelastung bei:

•Arsenfreies Displayglas
•Frei von bromhaltigen Flammschutzmitteln
•Quecksilberfreies Display mit LED-Hintergrundbeleuchtung
•Ohne PVC
•Recycelbares Gehäuse aus Aluminium und Glas
";2;False;0;;;Apple iPad 2 schwarz;apple-ipad-2-schwarz;True;True;PD-01076;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;9300;False;False;0;1;1;0;False;1;10000;;False;False;False;False;479.0000;479.0000;499.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40653,4073263889;54;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000633-apple-ipad-2-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000634-apple-ipad-2-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000635-apple-ipad-2-schwarz.jpg;1;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Apple iPad 2 weiß;Apple iPad 2. Generation weiß;"
Kapazität
 
16-GB-Flash-Laufwerk
32-GB-Flash-Laufwerk
64-GB-Flash-Laufwerk

Abmessungen und Gewicht
 
•Höhe: 241,2 mm
•Breite: 185,7 mm
•Tiefe: 8,8 mm
•Gewicht: 601 g
 
•Höhe: 241,2 mm
•Breite: 185,7 mm
•Tiefe: 8,8 mm
•Gewicht: 613 g
 
 
Drahtlose Technologie und Funknetz

•Wi-Fi (802.11a/b/g/n)
•Bluetooth 2.1 + EDR Technologie
•Wi-Fi + 3G Modell: UMTS/HSDPA/HSUPA (850, 900, 1900, 2100 MHz); GSM/EDGE (850, 900, 1800, 1900 MHz)
•Nur Datentransfer
•Wi-Fi (802.11a/b/g/n)
•Bluetooth 2.1 + EDR Technologie
Weitere Infos zu Wi-Fi + 3G
 

Display

 
•9,7"" Multi-Touch Hochglanz-Widescreendisplay mit LED-Hintergrundbeleuchtung und IPS-Technologie (24,63 cm Diagonale)
•Auflösung von 1024 x 768 Pixeln bei 132 ppi
•Fettabweisende Beschichtung
•Unterstützung für die Anzeige mehrerer Sprachen und Zeichen gleichzeitig
 
 
Chip
Speziell entwickelter, hochleistungsfähiger 1 GHz Dual-Core Apple A5 SOC (System-on-a-Chip) mit niedrigem Stromverbrauch
 
 
Kamera, Fotos, Videoaufnahme
 
•Rückkamera: Videoaufnahme, HD (720p) bis zu 30 fps mit Audio, Fotokamera mit 5-fach Digitalzoom
•Frontkamera: Videoaufnahme, VGA mit bis zu 30 fps mit Audio, Fotokamera in VGA-Qualität
•Fokussieren per Fingertipp für Videos und Fotos
•Geotagging für Fotos und Videos via Wi-Fi
 
 
Stromversorgung und Batterie
 
•Integrierte wiederaufladbare Lithium-Polymer-Batterie mit 25 Wattstunden
•Bis zu 10 Stunden Surfen im Web mit Wi-Fi, Video- oder Musikwiedergabe
•Aufladen über das Netzteil oder einen USB Anschluss am Computer
 
•Integrierte wiederaufladbare Lithium-Polymer-Batterie mit 25 Wattstunden
•Bis zu 10 Stunden Surfen im Web mit Wi-Fi, Video- oder Musikwiedergabe
•Bis zu 9 Stunden Batterielaufzeit beim Surfen im Internet über das 3G Datennetzwerk
•Aufladen über das Netzteil oder einen USB Anschluss am Computer
 
 
Ein- und Ausgabe
 
•30-poliger Dock-Anschluss
•3,5 mm Stereo-/Kopfhöreranschluss (Minianschluss)
•Integrierter Lautsprecher
•Mikrofon
 
•30-poliger Dock-Anschluss
•3,5 mm Stereo-/Kopfhöreranschluss (Minianschluss)
•Integrierter Lautsprecher
•Mikrofon
•Fach für Micro-SIM-Karte (nur beim Wi-Fi + 3G Modell)
 
 
Sensoren
 
•3-Achsen-Gyrosensor
•Beschleunigungssensor
•Umgebungslichtsensor
 
•3-Achsen-Gyrosensor
•Beschleunigungssensor
•Umgebungslichtsensor
 
 
Ortungsfunktion
 
•Wi-Fi
•Digitaler Kompass
 
•Wi-Fi
•Digitaler Kompass
•Assisted GPS
•Mobilfunknetz
 
 
Audiowiedergabe
 
•Frequenzbereich: 20 Hz bis 20.000 Hz
•Unterstützte Audioformate: HE-AAC (V1 und V2), AAC (8 bis 320 Kbit/s), Protected AAC (aus dem iTunes Store), MP3 (8 bis 320 Kbit/s), MP3 VBR, Audible (Formate 2, 3, 4, Audible Enhanced Audio, AAX und AAX+), Apple Lossless, AIFF und WAV
•Maximale Lautstärke vom Benutzer festlegbar
•Dolby Digital 5.1 Surround Sound Durchschleifen mit Apple Digital AV Adapter (separat erhältlich)
 
 
TV und Video
 
•Unterstützung für Bildschirmsynchronisation und Videoausgabe: bis zu 1080p mit dem Apple Digital AV Adapter oder dem Apple VGA-Adapter (Kabel separat erhältlich)
•Unterstützung für die Videoausgabe mit 576p und 480p mit dem Apple AV-Kabel (Komponentenvideo), mit 576i und 480i mit dem Apple AV-Kabel (Composite-Video)
•Unterstützte Videoformate: H.264 Video: bis zu 720p, 30 Bilder pro Sekunde, Main Profile Level 3.1 mit AAC-LC Audio mit bis zu 160 Kbit/s, 48 kHz, Stereo-Audio in den Formaten .m4v, .mp4 und .mov; MPEG-4 Video: bis zu 2,5 Mbit/s, 640 x 480 Pixel, 30 Bilder pro Sekunde, Simple Profile mit AAC-LC Audio mit bis zu 160 Kbit/s, 48 kHz, Stereo-Audio in den Formaten .m4v, .mp4 und .mov; Motion JPEG (M-JPEG): bis zu 35 Mbit/s, 1280 x 720 Pixel, 30 Bilder pro Sekunde, Audio im Format .ulaw, PCM Stereo-Audio im Format .avi
 
 
Unterstützte
E-Mail Anhänge
 
Anzeigbare Dokumenttypen: .jpg, .tiff, .gif (Bilder); .doc und .docx (Microsoft Word); .htm und .html (Webseiten); .key (Keynote); .numbers (Numbers); .pages (Pages); .pdf (Vorschau und Adobe Acrobat); .ppt und .pptx (Microsoft PowerPoint); .txt (Text); .rtf (Rich Text Format); .vcf (Kontaktdaten); .xls und .xlsx (Microsoft Excel)
 
Sprachen
 
•Sprachunterstützung für Englisch (USA), Englisch (Großbritannien), Französisch (Frankreich), Deutsch, traditionelles Chinesisch, vereinfachtes Chinesisch, Niederländisch, Italienisch, Spanisch, Portugiesisch (Brasilien), Portugiesisch (Portugal), Dänisch, Schwedisch, Finnisch, Norwegisch, Koreanisch, Japanisch, Russisch, Polnisch, Türkisch, Ukrainisch, Ungarisch, Arabisch, Thailändisch, Tschechisch, Griechisch, Hebräisch, Indonesisch, Malaiisch, Rumänisch, Slowakisch, Kroatisch, Katalanisch und Vietnamesisch
 
•Tastaturunterstützung für Englisch (USA), Englisch (Großbritannien), Französisch (Frankreich), Französisch (Kanada), Französisch (Schweiz), Deutsch, traditionelles Chinesisch (Handschrift, Pinyin, Zhuyin, Cangjie, Wubihua), vereinfachtes Chinesisch (Handschrift, Pinyin, Wubihua), Niederländisch, Italienisch, Spanisch, Portugiesisch (Brasilien), Portugiesisch (Portugal), Dänisch, Schwedisch, Finnisch, Norwegisch, Koreanisch, Japanisch (Romaji, 10 Tasten), Japanisch (Kana), Russisch, Polnisch, Türkisch, Ukrainisch, Estnisch, Ungarisch, Isländisch, Litauisch, Lettisch, Flämisch, Arabisch, Thailändisch, Tschechisch, Griechisch, Hebräisch, Indonesisch, Malaiisch, Rumänisch, Slowakisch, Kroatisch, Bulgarisch, Serbisch (Kyrillisch/Lateinisch), Katalanisch, Vietnamesisch, Tibetisch, Mazedonisch und Cherokee
 
•Wörterbuchunterstützung (aktiviert Textvorhersage und automatische Korrektur) für Englisch (USA), Englisch (Großbritannien), Französisch, Deutsch, traditionelles Chinesisch, vereinfachtes Chinesisch, Niederländisch, Italienisch, Spanisch, Portugiesisch (Brasilien), Portugiesisch (Portugal), Dänisch, Schwedisch, Finnisch, Norwegisch, Koreanisch, Japanisch (Romaji), Japanisch (Kana), Russisch, Polnisch, Türkisch, Ukrainisch, Ungarisch, Litauisch, Flämisch, Arabisch, Thailändisch, Tschechisch, Griechisch, Hebräisch, Indonesisch, Malaiisch, Rumänisch, Slowakisch, Kroatisch, Katalanisch, Vietnamesisch und Cherokee
 
Bedienungshilfen
 
•Unterstützung für die Wiedergabe von Inhalten mit erweiterten Untertiteln
•VoiceOver Bildschirmlesetechnologie
•Bildschirmfüllender Zoom
•Anzeigeoption ""Weiß-auf-Schwarz""
•Mono-Audioausgabe
 
 
Umgebungsbedingungen 

•Betriebstemperatur: 0 °C bis 35 °C
•Lagertemperatur: -20 °C bis 45 °C
•Relative Luftfeuchtigkeit: 5 % bis 95 %, nicht kondensierend
•Maximale Betriebshöhe: ca. 3.000 m über NN, ohne Druckausgleich
 
 
Voraussetzungen für Mac
 
•Mac mit USB 2.0 Anschluss
•Mac OS X 10.5.8 (oder neuer)
•iTunes 10.2 oder neuer empfohlen
(kostenlos ladbar unter www.itunes.com/de/download)
•iTunes Store Account
•Internetzugang
 
 
Voraussetzungen für Windows
 
•PC mit USB 2.0 Anschluss
•Windows 7, Windows Vista oder Windows XP Home oder Professional mit Service Pack 3 (oder neuer)
•iTunes 10.2 oder neuer empfohlen
(kostenlos ladbar unter www.itunes.com/de/download)
•iTunes Store Account
•Internetzugang
 
 
Lieferumfang
 
•iPad
•Dock Connector auf USB Kabel
•10W USB Power Adapter (Netzteil)
•Dokumentation
 
 
Umweltverträglichkeit
 
 
Das iPad steht exemplarisch für das Engagement von Apple in Sachen Umweltschutz. Die folgenden Merkmale des iPad tragen zu seiner geringeren Umweltbelastung bei:
•Arsenfreies Displayglas
•Frei von bromhaltigen Flammschutzmitteln
•Quecksilberfreies Display mit LED-Hintergrundbeleuchtung
•Ohne PVC
•Recycelbares Gehäuse aus Aluminium und Glas
";2;False;0;;;Apple iPad 2 weiß;apple-ipad-2-weiss;True;True;PD-01075;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;479.0000;0.0000;499.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40653,4018865741;54;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000627-apple-ipad-2-weis.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000628-apple-ipad-2-weis.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000629-apple-ipad-2-weis.jpg;1;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Apple MacBook Pro MC721D/A 15,4 Zoll Notebook;"Apple MacBook Pro MC721D/A 39.1 cm (15,4 Zoll) Notebook (Intel Core i7 2635QM, 2 GHz, 4GB RAM, 500GB HDD, AMD 6490M, DVD, Mac OS) ";"
Apple MacBook Pro MC721D/A
Intel Core i7 2635QM, 2 GHz

Unibody-Gehäuse. Am Anfang jedes MacBook Pro steht ein Werkstück aus Aluminium.Stark, leicht und schön in einem.
Das MacBook Pro ist aus einem einzigen Aluminiumblock gefertigt - eine technische Meisterleistung, bei der viele Bauteile durch ein einziges ersetzt werden. Das Ganze nennt sich Unibody. Gleich beim ersten Mal, wenn Sie ein MacBook Pro in der Hand haben, werden Sie den Unterschied spüren. Das Gehäuse ist dünner und leichter als andere Notebooks. Es sieht elegant aus. Und es fühlt sich stabil und robust an: perfekt für die Aktentasche, den Rucksack und natürlich auch für draußen.
 
Ein Display voll brillanter Ideen.
Alles, was Apple Designer und Ingenieure tun, ist von A bis Z durchdacht. Sie entschieden sich beim MacBook Pro für die LED-Hintergrundbeleuchtung, weil das Display damit sofort seine volle Helligkeit erreicht und trotzdem unglaublich dünn ist. Sie verwendeten eine durchgehende Oberfläche aus Glas, nicht nur weil es schön aussieht, sondern weil es dem ganzen Display Struktur verleiht. Und über dem Bildschirm haben sie die neue, integrierte FaceTime HD Kamera versteckt. So siehst du Freunde und Familie im Großformat - und dabei so gut wie nichts von der Kamera.
 
Magnetverschluss
Da der magnetische Verschluss keine beweglichen Teile hat, die abbrechen können oder an denen man hängen bleibt, ist das Öffnen und Schließen so einfach wie alles beim MacBook Pro.
 
Einfach auf alle Anschlüsse zugreifen.
Alle Anschlüsse am MacBook Pro - der MagSafe Netzanschluss, der Gigabit Ethernetanschluss, der Thunderbolt Anschluss, der USB Anschluss, der Karten-Steckplatz und der Audioeingang und -ausgang - sind ganz auf einer Seite des Notebooks integriert. So bleiben die Kabel schön geordnet und Geräte lassen sich schnell und einfach anschließen und auch wieder trennen.
 
Hinterlässt Eindruck. Aber nicht auf die Umwelt.
Weil Apple die vollständige Kontrolle über Design, Fertigung und Verpackung des MacBook Pro hat, hat Apple einen Vorsprung beim Umweltschutz. Die Technologie zur Hintergrundbeleuchtung des Displays spart Energie. Glas und Aluminium sind besonders recyclingfähig. Das MacBook Pro kommt fast ohne Giftstoffe aus. Und die Verpackung des 39,11 cm / 15,4"" Modells ist im Vergleich zum Vorgängermodell 34 Prozent kleiner. Das bedeutet nicht nur, dass für die Verpackungen weniger Bäume gefällt werden, es werden für den Transport auch weniger Flugzeugen, Güterzügen und LKWs benötigt.
 
Thunderbolt AnschlussDie Grafikleistung, die Sie brauchen, wenn Sie sie brauchen.
Alle MacBook Pro Modelle haben jetzt einen integrierten Intel HD Graphics 3000 Prozessor für die täglichen Aufgaben. Er codiert Videos schnell, ermöglicht HD Videotelefonate mit FaceTime und vieles mehr. Und auch Decodieren erledigt er effizienter, was bedeutet, dass Sie richtig lange DVDs und iTunes Filme schauen können. Bei anspruchsvollen Grafikprogrammen wechseln die 39,11 cm / 15,4"" MacBook Pro Modelle automatisch den Grafikprozessor und arbeiten mit den neuen leistungsstarken AMD Radeon Grafikprozessoren. Diese bieten verglichen mit den Vorgängermodellen die bis zu 3-fache Leistung. So sehen Sie bei 3D Spielen mehr Bilder pro Sekunde oder können schneller als je zuvor an HD Videoprojekten arbeiten.
 
Das neue Thunderbolt. Die schnellste, vielseitigste I/O Technologie in einem Notebook.
Stellen Sie sich vor, Sie könnten auf deinem Notebook auf mehrere unkomprimierte HD Videostreams zugreifen - und zwar so schnell, dass Sie einen HD Spielfilm in Echtzeit schneiden können. Thunderbolt macht genau das möglich. Mit Thunderbolt lassen sich superschnelle Peripheriegeräte der nächsten Generation an die Computer der nächsten Generation anschließen - angefangen beim MacBook Pro. Die Thunderbolt Pipeline ist ultraschnell und ultraflexibel. Sie ist über 12 Mal schneller als FireWire 800 und bis zu 20 Mal schneller als USB 2.0. Und sie bietet beispiellose Erweiterungsmöglichkeiten. Kurzum: Sie verändert alles, was Sie auf Ihrem Notebook machen können. Der Thunderbolt Anschluss gibt Ihnen Plug&Play Anschluss für eine völlig neue Welt von Thunderbolt Peripheriegeräten sowie für das Apple LED Cinema Display und andere Mini DisplayPort Peripheriegeräte. Sie können bis zu sechs Thunderbolt Geräte in Reihenschaltung anschließen, darunter auch Ihr Display. Außerdem unterstützt Thunderbolt Video und Achtkanal-Audio, sodass es auch möglich ist, HDMI-kompatible Geräte wie Fernseher oder Stereoanlagen über einen HDMI-Adapter anzuschließen. Auch aktuelle VGA-, DVI- und DisplayPort Adapter werden unterstützt.
 
Die neue FaceTime HD Kamera. Der Unterschied ist ganz klar.
Sehen Sie mehr von Ihren Freunden mit dem HD Widescreenformat - und zwar gestochen scharf. Die neue FaceTime HD Kamera bietet die dreifache Auflösung der vorherigen Kamera, was perfekt für das brillante Display mit LED-Hintergrundbeleuchtung ist. Außerdem arbeitet sie jetzt bei schwachem Licht noch besser. Sie können mit Ihren Freunden HD Telefonate in 720p von einem neuen MacBook Pro zu einem anderen führen. Außerdem sind auch Videotelefonate zu anderen Macs mit Intel Prozessor, zum iPhone 4 oder zum neuen iPod touch möglich.
 
Multi-Touch Trackpad - Jede Menge Platz für GestenMulti-Touch Trackpad. Fürs tägliche Handwerk.
Mit dem Multi-Touch Trackpad interagieren Sie auf ganz natürliche Art mit den Inhalten auf deinem Display. Und die glatte Glasoberfläche bietet jede Menge Platz für Gesten. Durch Auf- und Zuziehen können Sie ein- und auszoomen, durch Streichen in deinen Fotos blättern, durch Drehen ein Bild anpassen und vieles mehr. Das Trackpad kommt ohne Taste aus, sodass Sie überall klicken können. Wenn Sie aus der Welt des rechten Mausklicks kommen, können Sie diesen entweder mit zwei Fingern auslösen, oder Sie konfigurieren einen physischen Rechtsklick-Bereich auf dem Trackpad. Je mehr Sie mit dem Multi-Touch Trackpad vertraut sind, desto mehr werden Sie sich fragen, wie Sie jemals ohne ausgekommen sind.
 
Lange Laufzeit. Weniger aufladen. Mehr machen.
Das neue MacBook Pro bietet eine fantastische Batterielaufzeit und das mit leistungsstärkeren Prozessoren und schnelleren Grafikprozessoren. Die energieeffiziente Prozessorarchitektur mit integriertem Video-Encoder sowie das automatische Umschalten zwischen den Grafikprozessoren bei den 39,11 cm / 15,4"" Modellen helfen, die Batterielaufzeit weiter zu verbessern. So können Sie pro Ladung bis zu 7 Stunden ohne Kabel im Web surfen oder es für Liveauftritte oder auf ein Shooting mitnehmen. Die fortschrittlichen chemischen Eigenschaften und die Adaptive Charging Technologie sorgen dafür, dass die Batterie bis zu 1000 Ladezyklen durchlaufen kann. Und da die Batterie des MacBook Pro bis zu fünf Jahre hält, kommt das MacBook Pro in einem Zeitraum, in dem ein herkömmliches Notebook drei Batterien verbraucht, mit nur einer aus. Das ist für die Benutzer genauso gut, wie für die Umwelt. Apple verwendet eine neue, strengere Testmethode, um zu messen, welche Ergebnisse Sie unter realen Bedingungen erzielen, z. B. beim Surfen in einem Cafe oder wenn Sie die neuesten Webvideos ansehen. Und wie schneidet dieses MacBook Pro dabei verglichen mit der Vorgängergeneration ab? Es liefert die gleiche fantastische Leistung.
 
Hat beste Verbindungen.
Unterwegs haben Sie mit der 802.11n Technologie im MacBook Pro immer Verbindung. Das MacBook Pro findet automatisch verfügbare Netzwerke und Sie können sich mit einem Klick verbinden. Auch die drahtlose Bluetooth Technologie ist integriert, sodass Sie drahtloses Zubehör sofort nach dem Auspacken verwenden können.
 
DVDs superschnell brennen.
Homevideos, die Sie mit iMovie und iDVD gemacht haben, können Sie mit dem 8-fach SuperDrive Laufwerk des MacBook Pro superschnell auf eine DVD brennen. Das SuperDrive kann auch Double-Layer-DVDs (also DVDs mit fast 9 GB Speicherplatz) beschreiben, sodass es auch hervorragend für Datensicherungen geeignet ist.
 
Neue Intel Core i7 Prozessoren.
Neue Quad-Core Intel Core i7 Prozessoren sind Standard beim 39,11 cm / 15,4"" MacBook Pro. Alle Modelle verwenden die kürzlich optimierten Chipsets von Intel. Was heißt das für die neuen MacBook Pro Modelle? Kurz gesagt: Sie sind bis zu zwei Mal schneller als die Vorgängergeneration und erledigen auch anspruchsvolle Aufgaben wie HD Videoschnitt, Audiokompilierung oder Rendering mehrschichtiger Bilddateien unglaublich schnell. Und da Mac OS X Snow Leopard darauf ausgelegt ist, jeden Prozessorkern zu nutzen, holt das Betriebssystem wirklich alles an Leistung aus dem Prozessor heraus.
 
Schnellere Einzelchip-Mikroarchitektur.
Ob Sie einen Film ansehen, Ihren Blog auf den neuesten Stand bringen oder Fotos bearbeiten - die Daten müssen von A nach B gelangen, um verarbeitet werden zu können. Die neueste Intel Core Architektur bringt den Prozessor, den Cache, den Speichercontroller und den Grafikprozessor auf einem einzigen Chip unter. Deswegen müssen die Daten keine weiten Wege zurücklegen, was für Sie schnellere Performance und höhere Effizienz bedeutet.
 
Turbo Boost 2.0.
Angenommen, Sie arbeiten mit einem prozessorintensiven Programm wie Aperture 3 oder Final Cut Pro, das von einem Leistungsschub profitiert würde. Turbo Boost ist eine dynamische Technologie, die automatisch die Geschwindigkeit der aktiven Prozessorkerne auf 3,4 GHz erhöht. Turbo Boost 2.0 ist noch dynamischer und effizienter. Es wechselt die Kernfrequenz in kleineren Schritten als bisher, sodass der Prozessor die Leistung ohne Effizienzeinbußen verwalten kann. All das passiert im Hintergrund. Sie arbeiten einfach nur schneller.
 
Hyper-Threading.
Hyper-Threading ist jetzt Standard auf jedem MacBook Pro. Mit dieser Technologie können auf jedem Kern zwei Threads gleichzeitig laufen, Mac OS X erkennt also bei einem Quad-Core Prozessor acht und bei einem Dual-Core Prozessor vier virtuelle Kerne. Wenn Sie mehrere Programme gleichzeitig verwenden, verteilt der Prozessor die Aufgaben gleichmäßiger über eine größere Anzahl Kerne.
 
Integrierter Speichercontroller.
Mit schnellerem Speicherzugriff legt jeder Kern direkt mit der Verarbeitung der Daten los, statt auf ihr Eintreffen zu warten. Genau deshalb nutzt die neue Intel Core Architektur einen integrierten Speichercontroller, der den schnellen 1333 MHz Speicher direkt mit dem Prozessor verbindet und Ihre Programme immer die maximale Prozessorleistung zur Verfügung haben.
 
Energieeffiziente Grafik.
Dank der neuen Mikroarchitektur ist der Grafikprozessor auf dem gleichen Chip wie der Zentralprozessor und hat direkten Zugriff auf den L3-Cache. Kurze Wege bedeuten mehr Leistung. Der Grafikprozessor erhöht auch automatisch die Taktrate für noch höhere Auslastung. Ein integrierter Video-Encoder ermöglicht jetzt HD Videotelefonate mit FaceTime, und der effiziente Decoder sorgt für lange Batterielaufzeit, wenn Sie sich DVDs oder iTunes Filme ansiehen.
 
Mac OS X. Das fortschrittlichste Betriebssystem der Welt.
Mac OS X ist das Herz jedes MacBook Pro und Mac. Dieses Betriebssystem ist genau auf die integrierten Intel Multicore-Prozessoren und fortschrittlichen Grafikprozessoren zugeschnitten. Die neueste Version, Mac OS X Snow Leopard, basiert komplett auf einer 64-Bit-Architektur, genau wie alle anderen Programme, die mit dem Mac kommen. Das bedeutet: Alles, was Sie auf Ihrem MacBook Pro machen, passiert superschnell und mit einer unglaublichen Gesamtleistung.
 
Hat eine ganze Menge draufProgramme, ebenso leistungsstark wie benutzerfreundlich.
Weil Apple sowohl das MacBook Pro, wie auch die integrierte Software entwickelt, arbeitet alles perfekt zusammen. Und mit den Apple Programmen sind Sie ganz schnell vertraut, weil alle ähnlich funktionieren. Das heißt, wenn Sie ein Programm kennen, sind Sie auch schnell mit allen anderen vertraut. Außerdem weiß Apple genau, was mobile Produktivität bedeutet. Darum haben wir Funktionen wie Expose und Spaces hinzugefügt. Damit können Sie ganz einfach auf alles auf Ihrem MacBook Pro zugreifen. Expose zeigt sämtliche geöffneten Fenster nebeneinander, verkleinert sie und ordnet sie so, dass Sie den Inhalt jedes Fensters sehen können - ein Tastendruck oder eine Geste genügt. Und mit Spaces können Sie Fenster zusammen auf ihrem eigenen Schreibtisch oder Bereich gruppieren und ganz einfach zwischen diesen wechseln. Legen Sie einen Bereich zum Arbeiten fest, einen zum Spielen und einen für was auch immer. Mit Expose und Spaces haben Sie beim Multitasking auf einem Notebookdisplay einen riesigen Vorteil.
 
Darauf verzichten Sie beim Mac: PC-Viren.
Trojaner, Würmer, E-Mail Viren. Die digitale Welt kann ganz schön beängstigend sein. Zum Glück ist der Mac immun gegen die tausenden von Viren, die Windows Computer plagen. Denn Mac OS X kommt mit integrierten Sicherheitsmechanismen, die Sie schützen - ohne dass Sie etwas machen müssen. Und sollten doch mal potenzielle Sicherheitsrisiken auftreten, reagiert Apple sofort und stellt neue Softwareaktualisierungen und Sicherheitsverbesserungen bereit, die Sie automatisch laden und mit einem Klick installieren können.
 
Das automatische Backup rettet Ihren Tag. Und die Woche, den Monat ...
Backups müssen sein. Trotzdem vergissen Sie sie bestimmt hin und wieder. Deshalb kümmert sich jetzt das MacBook Pro um die Datensicherung. Time Machine, ein Programm, das auf jedem Mac dabei ist, sichert automatisch Ihr ganzes System auf einer externen Festplatte oder Time Capsule. Time Machine speichert eine Kopie von jeder Datei. Und es merkt sich, wie Ihr System an einem bestimmten Tag ausgesehen hat. So können Sie, wenn Sie wollen, die Zeit zurückdrehen und Ihren Mac wie in der Vergangenheit sehen.
 
Mit iMovie können Sie aus Ihren Videos großartige Filme machenAuch die täglichen Sachen machen mehr Spaß.
Anders als viele PC-Notebooks kommt das MacBook Pro mit allem, was Sie brauchen, um E-Mails zu senden, Kalender zu verwalten, Kontakte zu organisieren und mehr. Und Sie können schon wenige Minuten nach dem Auspacken damit loslegen. Denn jeder Mac kommt mit Mail, um E-Mails zu senden und empfangen, iCal zum Organisieren von Terminen und wichtigen Ereignissen, dem Adressbuch zum Verwalten von Kontakten, iTunes für alles, was mit Unterhaltung zu tun hat, und weiteren tollen und nützlichen Programmen, die Sie jeden Tag verwenden werden.
 
Der Mac App Store. Tausend weitere Gründe, den Mac zu lieben.
Über tausend Mac Apps sind nur einen Klick entfernt - im Mac App Store. Suchen Sie einfach Apps, die Ihnen gefallen, und klicken Sie einfach, um sie zu laden und zu installieren. Ohne Verpackung. Ohne CDs oder DVDs. Und ohne Probleme. Sie können die Apps nach Kategorien durchstöbern oder direkt etwas Bestimmtes suchen. Und Sie können einfach dafür sorgen, dass Ihre Apps up-to-date sind, denn Ihr Mac zeigt Ihnen an, wann Updates verfügbar sind.
 
iPhoto. Fotos ganz einfach verwalten, bearbeiten und teilen.
iPhoto ist ein benutzerfreundliches Programm für Fotos, mit dem Sie Ihre Bilder schnell organisieren, wiederfinden und verbessern können - sodass sie immer perfekt aussehen. Mit den iPhoto Funktionen ""Gesichter"", ""Orte"" und ""Ereignisse"" behalten Sie den Überblick über Ihre Fotos. Sie sagen Ihnen, wen Sie fotografiert haben, wo und wann. Und all das in den neuen Vollbildmodi.
 
iMovie. Und aus Homevideos werden Home-Blockbuster.
Homevideos müssen nicht langweilig sein. Mit iMovie können Sie aus Ihren Videos großartige Filme machen. Zum Beispiel Trailer im Hollywoodstil, mit denen Sie Ihr Publikum begeistern.
 
GarageBand. Großartige Musik machen, ganz einfachissimo.
Egal, ob Sie Musiktalent haben oder einfach nur neugierig sind - GarageBand ist genau das richtige Programm für Sie. Schließ einfach eine elektrische Gitarre oder ein USB Keyboard an. Und schon können Sie mit virtuellen Nachbildungen der bekanntesten Amps und Stompboxes der Welt sowie mit 100 Software-Instrumenten spielen.
";2;False;0;;;Apple MacBook Pro MC721D/A 15,4 Zoll Notebook;apple-macbook-pro-mc721da-154-zoll-notebook;True;True;P-0760;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;1483.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40652,8677546296;3;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000545-apple-macbook-pro-mc721da-154-zoll-notebook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000546-apple-macbook-pro-mc721da-154-zoll-notebook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000547-apple-macbook-pro-mc721da-154-zoll-notebook.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Apple MacBook Pro MD313D/A 13,3 Zoll Notebook;"Apple MacBook Pro MD313D/A 33,78cm (13,3"")";"
Apple MacBook Pro MD313D/A 13,3 Zoll Notebook
Intel Core i5  2x 2,40 GHz
 
Bis zu 2x schnellere Prozessoren. Bis zu 3x schnellere Grafik.
Quad-Core und Dual-Core Intel Prozessoren der nächsten Generation.
Das 13"" MacBook Pro gibt es jetzt mit einem 2,4 GHz Intel Core i5 Prozessor oder dem schnellsten Dual-Core Prozessor, den es gibt: dem 2,8 GHz Intel Core i7. Diese Prozessoren bieten Turbo Boost Geschwindigkeiten und machen das 13"" MacBook Pro bis zu doppelt so schnell wie die Vorgängergeneration.
 
Aber nur schnell ist uns nicht genug. Deshalb bieten die neuen 15"" und 17"" Modelle Quad-Core Leistung für praktisch alles, was du machen willst. Auch ein 2,4 GHz Quad-Core Intel Core i7 Prozessor mit Turbo Boost Geschwindigkeiten und bis zu 8 MB gemeinsam genutztem L3-Cache ist verfügbar. Auf MacBook Pro Modellen mit diesem Prozessor laufen Programme bis zu doppelt so schnell wie auf der besten Vorgängerkonfiguration.
 
Die Grafikleistung, die du brauchst, wenn du sie brauchst.
Alle MacBook Pro Modelle haben jetzt einen integrierten Intel HD Graphics 3000 Prozessor für die täglichen Aufgaben. Er codiert Videos schnell, ermöglicht HD Videotelefonate mit FaceTime und vieles mehr. Und auch Decodieren erledigt er effizienter, was bedeutet, dass du richtig lange DVDs und iTunes Filme schauen kannst.
 
Bei anspruchsvollen Grafikprogrammen wechseln die 15"" und 17"" MacBook Pro Modelle automatisch den Grafikprozessor und arbeiten mit den neuen leistungsstarken AMD Radeon Grafikprozessoren. Diese bieten verglichen mit den Vorgängermodellen die bis zu 3-fache Leistung.3 So siehst du bei 3D Spielen mehr Bilder pro Sekunde oder kannst schneller als je zuvor an HD Videoprojekten arbeiten.
 
Das neue Thunderbolt. Die schnellste, vielseitigste I/O Technologie in einem Notebook.
Stell dir vor, du könntest auf deinem Notebook auf mehrere unkomprimierte HD Videostreams zugreifen - und zwar so schnell, dass du einen HD Spielfilm in Echtzeit schneiden kannst. Thunderbolt macht genau das möglich. Mit Thunderbolt lassen sich superschnelle Peripheriegeräte der nächsten Generation an die Computer der nächsten Generation anschließen - angefangen beim MacBook Pro. Die Thunderbolt Pipeline ist ultraschnell und ultraflexibel. Sie ist über 12 Mal schneller als FireWire 800 und bis zu 20 Mal schneller als USB 2.0. Und sie bietet beispiellose Erweiterungsmöglichkeiten. Kurzum: Sie verändert alles, was du auf deinem Notebook machen kannst.
 
Der Thunderbolt Anschluss gibt dir Plug&Play Anschluss für eine völlig neue Welt von Thunderbolt Peripheriegeräten sowie für das Apple LED Cinema Display und andere Mini DisplayPort Peripheriegeräte. Du kannst bis zu sechs Thunderbolt Geräte in Reihenschaltung anschließen, darunter auch dein Display. Außerdem unterstützt Thunderbolt Video und Achtkanal-Audio, sodass es auch möglich ist, HDMI-kompatible Geräte wie Fernseher oder Stereoanlagen über einen HDMI-Adapter anzuschließen. Auch aktuelle VGA-, DVI- und DisplayPort Adapter werden unterstützt.
 
Die neue FaceTime HD Kamera. Der Unterschied ist ganz klar.
Sieh mehr von deinen Freunden mit dem HD Widescreenformat - und zwar gestochen scharf. Die neue FaceTime HD Kamera bietet die dreifache Auflösung der vorherigen Kamera, was perfekt für das brillante Display mit LED-Hintergrundbeleuchtung ist. Außerdem arbeitet sie jetzt bei schwachem Licht noch besser. Du kannst mit deinen Freunden HD Telefonate in 720p von einem neuen MacBook Pro zu einem anderen führen. Außerdem sind auch Videotelefonate zu anderen Macs mit Intel Prozessor5, zum iPhone 4 oder zum neuen iPod touch möglich.
 
Multi-Touch Trackpad. Fürs tägliche Handwerk.
Mit dem Multi-Touch Trackpad interagierst du auf ganz natürliche Art mit den Inhalten auf deinem Display. Und die glatte Glasoberfläche bietet jede Menge Platz für Gesten. Durch Auf- und Zuziehen kannst du ein- und auszoomen, durch Streichen in deinen Fotos blättern, durch Drehen ein Bild anpassen und vieles mehr. Das Trackpad kommt ohne Taste aus, sodass du überall klicken kannst. Wenn du aus der Welt des rechten Mausklicks kommst, kannst du diesen entweder mit zwei Fingern auslösen, oder du konfigurierst einen physischen Rechtsklick-Bereich auf dem Trackpad. Je mehr du mit dem Multi-Touch Trackpad vertraut bist, desto mehr wirst du dich fragen, wie du jemals ohne ausgekommen bist.
 
Lange Laufzeit. Weniger aufladen. Mehr machen.
Das neue MacBook Pro bietet eine fantastische Batterielaufzeit und das mit leistungsstärkeren Prozessoren und schnelleren Grafikprozessoren. Die energieeffiziente Prozessorarchitektur mit integriertem Video-Encoder sowie das automatische Umschalten zwischen den Grafikprozessoren bei den 15"" und 17"" Modellen helfen, die Batterielaufzeit weiter zu verbessern. So kannst du pro Ladung bis zu 7 Stunden ohne Kabel im Web surfen6 oder es für Liveauftritte oder auf ein Shooting mitnehmen. Die fortschrittlichen chemischen Eigenschaften und die Adaptive Charging Technologie sorgen dafür, dass die Batterie bis zu 1000 Ladezyklen durchlaufen kann.7 Und da die Batterie des MacBook Pro bis zu fünf Jahre hält, kommt das MacBook Pro in einem Zeitraum, in dem ein herkömmliches Notebook drei Batterien verbraucht, mit nur einer aus. Das ist für die Benutzer genauso gut, wie für die Umwelt.
 
Apple verwendet eine neue, strengere Testmethode, um zu messen, welche Ergebnisse du unter realen Bedingungen erzielst, z. B. beim Surfen in einem Café oder wenn du die neuesten Webvideos ansiehst. Und wie schneidet dieses MacBook Pro dabei verglichen mit der Vorgängergeneration ab? Es liefert die gleiche fantastische Leistung.
 
Hat beste Verbindungen.
Unterwegs hast du mit der 802.11n Technologie im MacBook Pro immer Verbindung.8 Das MacBook Pro findet automatisch verfügbare Netzwerke und du kannst dich mit einem Klick verbinden. Auch die drahtlose Bluetooth Technologie ist integriert, sodass du drahtloses Zubehör sofort nach dem Auspacken verwenden kannst.
 
Immer Anschluss finden.
Mit dem neuen Thunderbolt Anschluss kannst du bis zu sechs Geräte in Reihenschaltung anschließen, darunter auch dein Display. So bekommst du eine vollwertige Workstation. Für die Anbindung von iPad, iPod, iPhone, Digitalkameras und externen Festplatten gibt es zwei USB 2.0 Anschlüsse (drei beim 17"" MacBook Pro) und einen FireWire 800 Anschluss.
 
Der neue SDXC Kartensteckplatz der 13"" und 15"" MacBook Pro Modelle unterstützt bis zu 64 GB Karten und macht es leicht, alle deine Fotos auf und von deinem MacBook Pro zu übertragen, damit du sie sofort bearbeiten und teilen kannst. Und der ExpressCard/34 Steckplatz am 17"" MacBook Pro ist perfekt für einen eSATA Adapter geeignet oder sogar für eine 3G Karte für die drahtlose Kommunikation, wenn kein Wi-Fi Netzwerk vorhanden ist.
 
DVDs superschnell brennen.
Homevideos, die du mit iMovie und iDVD gemacht hast, kannst du mit dem 8-fach SuperDrive Laufwerk des MacBook Pro superschnell auf eine DVD brennen. Das SuperDrive kann auch Double-Layer-DVDs (also DVDs mit fast 9 GB Speicherplatz) beschreiben, sodass es auch hervorragend für Datensicherungen geeignet ist.
";2;False;0;;;Apple MacBook Pro MD313D/A 13,3 Zoll Notebook;apple-macbook-pro-md313da-133-zoll-notebook;True;True;P-0740;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;1099.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40652,639537037;3;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000456-apple-macbook-pro-md313da-133-zoll-notebook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000457-apple-macbook-pro-md313da-133-zoll-notebook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000458-apple-macbook-pro-md313da-133-zoll-notebook.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Apple MacBook Pro MC725D/A 17 Zoll Notebook;"Apple MacBook Pro MC725D/A 43.2 cm (17 Zoll) Notebook (Intel Core i7 2720QM, 2,2 GHz, 4GB RAM, 750GB HDD, AMD 6750M, DVD, Mac OS) ";"
Apple MacBook Pro MC725D/A
Intel Core i7 2720QM, 2,2 GHz
 
Stark, leicht und schön in einem.
Das MacBook Pro ist aus einem einzigen Aluminiumblock gefertigt - eine technische Meisterleistung, bei der viele Bauteile durch ein einziges ersetzt werden. Das Ganze nennt sich Unibody. Gleich beim ersten Mal, wenn Sie ein MacBook Pro in der Hand haben, werden Sie den Unterschied spüren. Das Gehäuse ist dünner und leichter als andere Notebooks. Es sieht elegant aus. Und es fühlt sich stabil und robust an: perfekt für die Aktentasche, den Rucksack und natürlich auch für draußen.
 
Ein Display voll brillanter Ideen.
Alles, was Apple Designer und Ingenieure tun, ist von A bis Z durchdacht. Sie entschieden sich beim MacBook Pro für die LED-Hintergrundbeleuchtung, weil das Display damit sofort seine volle Helligkeit erreicht und trotzdem unglaublich dünn ist. Sie verwendeten eine durchgehende Oberfläche aus Glas, nicht nur weil es schön aussieht, sondern weil es dem ganzen Display Struktur verleiht. Und über dem Bildschirm haben sie die neue, integrierte FaceTime HD Kamera versteckt. So siehst du Freunde und Familie im Großformat - und dabei so gut wie nichts von der Kamera.
 
Magnetverschluss
Da der magnetische Verschluss keine beweglichen Teile hat, die abbrechen können oder an denen man hängen bleibt, ist das Öffnen und Schließen so einfach wie alles beim MacBook Pro.
 
Einfach auf alle Anschlüsse zugreifen.
Alle Anschlüsse am MacBook Pro - der MagSafe Netzanschluss, der Gigabit Ethernetanschluss, der Thunderbolt Anschluss, der USB Anschluss, der Karten-Steckplatz und der Audioeingang und -ausgang - sind ganz auf einer Seite des Notebooks integriert. So bleiben die Kabel schön geordnet und Geräte lassen sich schnell und einfach anschließen und auch wieder trennen.
 
Hinterlässt Eindruck. Aber nicht auf die Umwelt.
Weil Apple die vollständige Kontrolle über Design, Fertigung und Verpackung des MacBook Pro hat, hat Apple einen Vorsprung beim Umweltschutz. Die Technologie zur Hintergrundbeleuchtung des Displays spart Energie. Glas und Aluminium sind besonders recyclingfähig. Das MacBook Pro kommt fast ohne Giftstoffe aus. Und die Verpackung des 43,18 cm / 17"" Modells ist im Vergleich zum Vorgängermodell 34 Prozent kleiner. Das bedeutet nicht nur, dass für die Verpackungen weniger Bäume gefällt werden, es werden für den Transport auch weniger Flugzeugen, Güterzügen und LKWs benötigt.
 
Thunderbolt AnschlussDie Grafikleistung, die Sie brauchen, wenn Sie sie brauchen.
Alle MacBook Pro Modelle haben jetzt einen integrierten Intel HD Graphics 3000 Prozessor für die täglichen Aufgaben. Er codiert Videos schnell, ermöglicht HD Videotelefonate mit FaceTime und vieles mehr. Und auch Decodieren erledigt er effizienter, was bedeutet, dass Sie richtig lange DVDs und iTunes Filme schauen können. Bei anspruchsvollen Grafikprogrammen wechseln die 43,18 cm / 17"" MacBook Pro Modelle automatisch den Grafikprozessor und arbeiten mit den neuen leistungsstarken AMD Radeon Grafikprozessoren. Diese bieten verglichen mit den Vorgängermodellen die bis zu 3-fache Leistung. So sehen Sie bei 3D Spielen mehr Bilder pro Sekunde oder können schneller als je zuvor an HD Videoprojekten arbeiten.
 
Das neue Thunderbolt. Die schnellste, vielseitigste I/O Technologie in einem Notebook.
Stellen Sie sich vor, Sie könnten auf deinem Notebook auf mehrere unkomprimierte HD Videostreams zugreifen - und zwar so schnell, dass Sie einen HD Spielfilm in Echtzeit schneiden können. Thunderbolt macht genau das möglich. Mit Thunderbolt lassen sich superschnelle Peripheriegeräte der nächsten Generation an die Computer der nächsten Generation anschließen - angefangen beim MacBook Pro. Die Thunderbolt Pipeline ist ultraschnell und ultraflexibel. Sie ist über 12 Mal schneller als FireWire 800 und bis zu 20 Mal schneller als USB 2.0. Und sie bietet beispiellose Erweiterungsmöglichkeiten. Kurzum: Sie verändert alles, was Sie auf Ihrem Notebook machen können. Der Thunderbolt Anschluss gibt Ihnen Plug&Play Anschluss für eine völlig neue Welt von Thunderbolt Peripheriegeräten sowie für das Apple LED Cinema Display und andere Mini DisplayPort Peripheriegeräte. Sie können bis zu sechs Thunderbolt Geräte in Reihenschaltung anschließen, darunter auch Ihr Display. Außerdem unterstützt Thunderbolt Video und Achtkanal-Audio, sodass es auch möglich ist, HDMI-kompatible Geräte wie Fernseher oder Stereoanlagen über einen HDMI-Adapter anzuschließen. Auch aktuelle VGA-, DVI- und DisplayPort Adapter werden unterstützt.
 
Die neue FaceTime HD Kamera. Der Unterschied ist ganz klar.
Sehen Sie mehr von Ihren Freunden mit dem HD Widescreenformat - und zwar gestochen scharf. Die neue FaceTime HD Kamera bietet die dreifache Auflösung der vorherigen Kamera, was perfekt für das brillante Display mit LED-Hintergrundbeleuchtung ist. Außerdem arbeitet sie jetzt bei schwachem Licht noch besser. Sie können mit Ihren Freunden HD Telefonate in 720p von einem neuen MacBook Pro zu einem anderen führen. Außerdem sind auch Videotelefonate zu anderen Macs mit Intel Prozessor, zum iPhone 4 oder zum neuen iPod touch möglich.
 
Multi-Touch Trackpad - Jede Menge Platz für GestenMulti-Touch Trackpad. Fürs tägliche Handwerk.
Mit dem Multi-Touch Trackpad interagieren Sie auf ganz natürliche Art mit den Inhalten auf deinem Display. Und die glatte Glasoberfläche bietet jede Menge Platz für Gesten. Durch Auf- und Zuziehen können Sie ein- und auszoomen, durch Streichen in deinen Fotos blättern, durch Drehen ein Bild anpassen und vieles mehr. Das Trackpad kommt ohne Taste aus, sodass Sie überall klicken können. Wenn Sie aus der Welt des rechten Mausklicks kommen, können Sie diesen entweder mit zwei Fingern auslösen, oder Sie konfigurieren einen physischen Rechtsklick-Bereich auf dem Trackpad. Je mehr Sie mit dem Multi-Touch Trackpad vertraut sind, desto mehr werden Sie sich fragen, wie Sie jemals ohne ausgekommen sind.
 
Lange Laufzeit. Weniger aufladen. Mehr machen.
Das neue MacBook Pro bietet eine fantastische Batterielaufzeit und das mit leistungsstärkeren Prozessoren und schnelleren Grafikprozessoren. Die energieeffiziente Prozessorarchitektur mit integriertem Video-Encoder sowie das automatische Umschalten zwischen den Grafikprozessoren bei den 43,18 cm / 17"" Modellen helfen, die Batterielaufzeit weiter zu verbessern. So können Sie pro Ladung bis zu 7 Stunden ohne Kabel im Web surfen oder es für Liveauftritte oder auf ein Shooting mitnehmen. Die fortschrittlichen chemischen Eigenschaften und die Adaptive Charging Technologie sorgen dafür, dass die Batterie bis zu 1000 Ladezyklen durchlaufen kann. Und da die Batterie des MacBook Pro bis zu fünf Jahre hält, kommt das MacBook Pro in einem Zeitraum, in dem ein herkömmliches Notebook drei Batterien verbraucht, mit nur einer aus. Das ist für die Benutzer genauso gut, wie für die Umwelt. Apple verwendet eine neue, strengere Testmethode, um zu messen, welche Ergebnisse Sie unter realen Bedingungen erzielen, z. B. beim Surfen in einem Cafe oder wenn Sie die neuesten Webvideos ansehen. Und wie schneidet dieses MacBook Pro dabei verglichen mit der Vorgängergeneration ab? Es liefert die gleiche fantastische Leistung.
 
Hat beste Verbindungen.
Unterwegs haben Sie mit der 802.11n Technologie im MacBook Pro immer Verbindung. Das MacBook Pro findet automatisch verfügbare Netzwerke und Sie können sich mit einem Klick verbinden. Auch die drahtlose Bluetooth Technologie ist integriert, sodass Sie drahtloses Zubehör sofort nach dem Auspacken verwenden können.
 
DVDs superschnell brennen.
Homevideos, die Sie mit iMovie und iDVD gemacht haben, können Sie mit dem 8-fach SuperDrive Laufwerk des MacBook Pro superschnell auf eine DVD brennen. Das SuperDrive kann auch Double-Layer-DVDs (also DVDs mit fast 9 GB Speicherplatz) beschreiben, sodass es auch hervorragend für Datensicherungen geeignet ist.
 
Neue Intel Core i7 Prozessoren.
Neue Quad-Core Intel Core i7 Prozessoren sind Standard beim 43,18 cm / 17"" MacBook Pro. Alle Modelle verwenden die kürzlich optimierten Chipsets von Intel. Was heißt das für die neuen MacBook Pro Modelle? Kurz gesagt: Sie sind bis zu zwei Mal schneller als die Vorgängergeneration und erledigen auch anspruchsvolle Aufgaben wie HD Videoschnitt, Audiokompilierung oder Rendering mehrschichtiger Bilddateien unglaublich schnell. Und da Mac OS X Snow Leopard darauf ausgelegt ist, jeden Prozessorkern zu nutzen, holt das Betriebssystem wirklich alles an Leistung aus dem Prozessor heraus.
 
Schnellere Einzelchip-Mikroarchitektur.
Ob Sie einen Film ansehen, Ihren Blog auf den neuesten Stand bringen oder Fotos bearbeiten - die Daten müssen von A nach B gelangen, um verarbeitet werden zu können. Die neueste Intel Core Architektur bringt den Prozessor, den Cache, den Speichercontroller und den Grafikprozessor auf einem einzigen Chip unter. Deswegen müssen die Daten keine weiten Wege zurücklegen, was für Sie schnellere Performance und höhere Effizienz bedeutet.
 
Turbo Boost 2.0.
Angenommen, Sie arbeiten mit einem prozessorintensiven Programm wie Aperture 3 oder Final Cut Pro, das von einem Leistungsschub profitiert würde. Turbo Boost ist eine dynamische Technologie, die automatisch die Geschwindigkeit der aktiven Prozessorkerne auf 3,4 GHz erhöht. Turbo Boost 2.0 ist noch dynamischer und effizienter. Es wechselt die Kernfrequenz in kleineren Schritten als bisher, sodass der Prozessor die Leistung ohne Effizienzeinbußen verwalten kann. All das passiert im Hintergrund. Sie arbeiten einfach nur schneller.
 
Hyper-Threading.
Hyper-Threading ist jetzt Standard auf jedem MacBook Pro. Mit dieser Technologie können auf jedem Kern zwei Threads gleichzeitig laufen, Mac OS X erkennt also bei einem Quad-Core Prozessor acht und bei einem Dual-Core Prozessor vier virtuelle Kerne. Wenn Sie mehrere Programme gleichzeitig verwenden, verteilt der Prozessor die Aufgaben gleichmäßiger über eine größere Anzahl Kerne.
 
Integrierter Speichercontroller.
Mit schnellerem Speicherzugriff legt jeder Kern direkt mit der Verarbeitung der Daten los, statt auf ihr Eintreffen zu warten. Genau deshalb nutzt die neue Intel Core Architektur einen integrierten Speichercontroller, der den schnellen 1333 MHz Speicher direkt mit dem Prozessor verbindet und Ihre Programme immer die maximale Prozessorleistung zur Verfügung haben.
 
Energieeffiziente Grafik.
Dank der neuen Mikroarchitektur ist der Grafikprozessor auf dem gleichen Chip wie der Zentralprozessor und hat direkten Zugriff auf den L3-Cache. Kurze Wege bedeuten mehr Leistung. Der Grafikprozessor erhöht auch automatisch die Taktrate für noch höhere Auslastung. Ein integrierter Video-Encoder ermöglicht jetzt HD Videotelefonate mit FaceTime, und der effiziente Decoder sorgt für lange Batterielaufzeit, wenn Sie sich DVDs oder iTunes Filme ansiehen.
 
Mac OS X. Das fortschrittlichste Betriebssystem der Welt.
Mac OS X ist das Herz jedes MacBook Pro und Mac. Dieses Betriebssystem ist genau auf die integrierten Intel Multicore-Prozessoren und fortschrittlichen Grafikprozessoren zugeschnitten. Die neueste Version, Mac OS X Snow Leopard, basiert komplett auf einer 64-Bit-Architektur, genau wie alle anderen Programme, die mit dem Mac kommen. Das bedeutet: Alles, was Sie auf Ihrem MacBook Pro machen, passiert superschnell und mit einer unglaublichen Gesamtleistung.
 
Hat eine ganze Menge draufProgramme, ebenso leistungsstark wie benutzerfreundlich.
Weil Apple sowohl das MacBook Pro, wie auch die integrierte Software entwickelt, arbeitet alles perfekt zusammen. Und mit den Apple Programmen sind Sie ganz schnell vertraut, weil alle ähnlich funktionieren. Das heißt, wenn Sie ein Programm kennen, sind Sie auch schnell mit allen anderen vertraut. Außerdem weiß Apple genau, was mobile Produktivität bedeutet. Darum haben wir Funktionen wie Expose und Spaces hinzugefügt. Damit können Sie ganz einfach auf alles auf Ihrem MacBook Pro zugreifen. Expose zeigt sämtliche geöffneten Fenster nebeneinander, verkleinert sie und ordnet sie so, dass Sie den Inhalt jedes Fensters sehen können - ein Tastendruck oder eine Geste genügt. Und mit Spaces können Sie Fenster zusammen auf ihrem eigenen Schreibtisch oder Bereich gruppieren und ganz einfach zwischen diesen wechseln. Legen Sie einen Bereich zum Arbeiten fest, einen zum Spielen und einen für was auch immer. Mit Expose und Spaces haben Sie beim Multitasking auf einem Notebookdisplay einen riesigen Vorteil.
 
Darauf verzichten Sie beim Mac: PC-Viren.
Trojaner, Würmer, E-Mail Viren. Die digitale Welt kann ganz schön beängstigend sein. Zum Glück ist der Mac immun gegen die tausenden von Viren, die Windows Computer plagen. Denn Mac OS X kommt mit integrierten Sicherheitsmechanismen, die Sie schützen - ohne dass Sie etwas machen müssen. Und sollten doch mal potenzielle Sicherheitsrisiken auftreten, reagiert Apple sofort und stellt neue Softwareaktualisierungen und Sicherheitsverbesserungen bereit, die Sie automatisch laden und mit einem Klick installieren können.
 
Das automatische Backup rettet Ihren Tag. Und die Woche, den Monat ...
Backups müssen sein. Trotzdem vergissen Sie sie bestimmt hin und wieder. Deshalb kümmert sich jetzt das MacBook Pro um die Datensicherung. Time Machine, ein Programm, das auf jedem Mac dabei ist, sichert automatisch Ihr ganzes System auf einer externen Festplatte oder Time Capsule. Time Machine speichert eine Kopie von jeder Datei. Und es merkt sich, wie Ihr System an einem bestimmten Tag ausgesehen hat. So können Sie, wenn Sie wollen, die Zeit zurückdrehen und Ihren Mac wie in der Vergangenheit sehen.
 
Mit iMovie können Sie aus Ihren Videos großartige Filme machenAuch die täglichen Sachen machen mehr Spaß.
Anders als viele PC-Notebooks kommt das MacBook Pro mit allem, was Sie brauchen, um E-Mails zu senden, Kalender zu verwalten, Kontakte zu organisieren und mehr. Und Sie können schon wenige Minuten nach dem Auspacken damit loslegen. Denn jeder Mac kommt mit Mail, um E-Mails zu senden und empfangen, iCal zum Organisieren von Terminen und wichtigen Ereignissen, dem Adressbuch zum Verwalten von Kontakten, iTunes für alles, was mit Unterhaltung zu tun hat, und weiteren tollen und nützlichen Programmen, die Sie jeden Tag verwenden werden.
 
Der Mac App Store. Tausend weitere Gründe, den Mac zu lieben.
Über tausend Mac Apps sind nur einen Klick entfernt - im Mac App Store. Suchen Sie einfach Apps, die Ihnen gefallen, und klicken Sie einfach, um sie zu laden und zu installieren. Ohne Verpackung. Ohne CDs oder DVDs. Und ohne Probleme. Sie können die Apps nach Kategorien durchstöbern oder direkt etwas Bestimmtes suchen. Und Sie können einfach dafür sorgen, dass Ihre Apps up-to-date sind, denn Ihr Mac zeigt Ihnen an, wann Updates verfügbar sind.
 
iPhoto. Fotos ganz einfach verwalten, bearbeiten und teilen.
iPhoto ist ein benutzerfreundliches Programm für Fotos, mit dem Sie Ihre Bilder schnell organisieren, wiederfinden und verbessern können - sodass sie immer perfekt aussehen. Mit den iPhoto Funktionen ""Gesichter"", ""Orte"" und ""Ereignisse"" behalten Sie den Überblick über Ihre Fotos. Sie sagen Ihnen, wen Sie fotografiert haben, wo und wann. Und all das in den neuen Vollbildmodi.
 
iMovie. Und aus Homevideos werden Home-Blockbuster.
Homevideos müssen nicht langweilig sein. Mit iMovie können Sie aus Ihren Videos großartige Filme machen. Zum Beispiel Trailer im Hollywoodstil, mit denen Sie Ihr Publikum begeistern.
 
GarageBand. Großartige Musik machen, ganz einfachissimo.
Egal, ob Sie Musiktalent haben oder einfach nur neugierig sind - GarageBand ist genau das richtige Programm für Sie. Schließ einfach eine elektrische Gitarre oder ein USB Keyboard an. Und schon können Sie mit virtuellen Nachbildungen der bekanntesten Amps und Stompboxes der Welt sowie mit 100 Software-Instrumenten spielen.  
";2;False;0;;;Apple MacBook Pro MC725D/A 17 Zoll Notebook;apple-macbook-pro-mc725da-17-zoll-notebook;True;True;P-0700;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;2299.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40652,5987037037;3;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000312-apple-macbook-pro-mc725da-17-zoll-notebook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000313-apple-macbook-pro-mc725da-17-zoll-notebook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000314-apple-macbook-pro-mc725da-17-zoll-notebook.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Apple iPod Nano 8 GB 6. Gen. verschiedene Farben;Apple iPod Nano 8 GB 6. Generation verschiedene Farben;"
Der Remix für Ihre Finger
Der iPod nano mit Multi-Touch ist einfach, intuitiv und macht jede Menge Spaß - wie Ihre Musik. Und er ist jetzt noch kleiner, damit Musik bei allem, was Sie machen, eine größere Rolle spielen kann.
 
Musik. Fühlen Sie den Beat
Ihre Greatest Hits. Zum Anfassen
Die besten Dinge im Leben kommen mit Soundtrack. Und genau da glänzt der iPod nano. Mit dem Multi-Touch Display können Sie Ihre Musik ganz neu erleben. Ein Tipp genügt und er spielt, was Sie hören wollen. Stöbern Sie in Ihrer Musik nach Songs, Alben, Interpreten, Wiedergabelisten, Genres oder Komponisten - streichen Sie dazu über den Homescreen. Sie können sogar die Symbole auf dem Homescreen neu ordnen, damit alles so ist, wie Sie es wollen.
 
Das ist ein echter Musikclip
Mit dem neuen integrierten Clip können Sie mit Ihren Lieblingssongs am Ärmel (oder in der Tasche, Jacke oder Hose) wandern, laufen, Rad fahren und abrocken. Und das Cover zum Song, der gerade läuft, passt perfekt auf das Display.
 
Rock around the clock
Die integrierte aufladbare Lithium-Ionen-Batterie sorgt für 24 Stunden Musik nonstop. Wenn Sie sich den 8 GB oder 16 GB iPod nano anklippen, haben Sie genug Songs für den Weg zur Arbeit, fürs Training und mehr.
 
Songs aus dem Finger schütteln
Überlassen Sie alles dem Zufall. Einfach den iPod nano kurz schütteln und er springt zu einem anderen Song aus Ihrer Sammlung. Schütteln ist perfekt, wenn Ihnen gerade nicht nach einer bestimmten Musik ist. Lassen Sie sich einfach überraschen.
 
Genius. Ihr Mixmaster
 
Eingebauter Clip

 
Ihr persönlicher DJ
Angenommen, Sie hören einen Song, der Ihnen gut gefällt, und möchten ähnliche hören. Ein Tipp auf Genius genügt. Genius findet weitere Songs auf Ihrem iPod nano, die gut dazu passen und erstellt eine Genius Wiedergabeliste für Sie. Wenn Sie einen Mix wollen, auf den Sie selbst nie gekommen wären, erstellen Sie einen Genius Mix in iTunes und synchronisieren ihn mit Ihrem iPod nano. Tippen Sie auf das Symbol für Genius Mixe und entdecken Sie Songs, die Sie lange nicht mehr gehört haben, oder Musik, von der Sie gar nicht mehr wussten, dass Sie sie haben.
 
FM Radio. Und Sie haben alles auf dem Sender
Radio nano
Mit dem iPod nano können Sie auf der Radiowelle surfen. Der FM Tuner zeigt Ihnen den Interpreten, Song oder Sender, der gerade läuft. Ein Tipp genügt und Sie sehen die Radiosteuerungen. Streichen Sie über den Tuner, um den Sender zu wechseln, und stellen Sie dann Ihre Lieblingssender per Fingertipp ein.
 
Live-Pause
Wenn Sie Ihre Lieblingssendung im Radio einmal kurz unterbrechen müssen, verpassen Sie dank Live-Pause trotzdem keinen einzigen Beat. Einfach Tippen und Sendung oder Song werden angehalten. Noch mal Tippen und es geht da weiter, wo Sie aufgehört haben. Sie können sogar bis zu 15 Minuten zurückspulen und dann vorspulen, um wieder live dabei zu sein.
 
Fitness. Treffen Sie Ihren neuen Trainer
 
Anklippen und los geht´s
Das neue Design des iPod nano hilft Ihnen fit zu bleiben. Weil er so klein und tragbar ist, ist er auch beim Joggen, Wandern und im Fitnessstudio immer dabei. Klippen Sie ihn an und steuern Sie Ihre Musik mit nur einem Tippen oder Streichen, sodass Sie sich voll auf Ihr Workout konzentrieren können. Ob Laufen, Walken oder der Weg zum Fitnessstudio - für den kleinen iPod nano ist kein Weg zu weit.
 
Schritte zum Fitbleiben
Sie können den iPod nano auch als Schrittzähler verwenden. Er zählt Ihre Schritte und hilft Ihnen beim Erreichen Ihrer Fitnessziele. Einfach anklippen und los geht´s. Sie können eine tägliche Schrittvorgabe festlegen und Ihre Fortschritte sehen, wenn Sie Ihre Daten auf die Nike+ Website laden.
 
Rocken Sie Ihr Training
Ob beim Joggen oder im Fitnessstudio, mit dem Nike + iPod Sport Kit (separat erhältlich) motiviert Sie der iPod nano vom Warm Up bis zum Cool Down. Ziehen Sie Ihre Nike+ Joggingschuhe an und klippen Sie sich den iPod nano an. Sehen Sie wie Sie Kilometer für Kilometer zurücklegen und hören Sie das Sprachfeedback in Echtzeit, während Ihre Songs laufen. Schließen Sie den iPod nano im Fitnessstudio an ein Gerät an, das mit Nike + iPod kompatibel ist. So zeichnet er Ihre Geschwindigkeit, die Dauer und die Laufstrecke auf, während Sie Ihr Training rocken.
 
iTunes. Damit der iPod was zu spielen hat
Alles für gute Unterhaltung
iTunes ist der beste Weg, Ihren iPod nano mit den neuesten Hits, Podcasts, Hörbüchern und vielem mehr zu füllen. Und auch die beste Art, Ihre immer weiter wachsende Sammlung digitaler Medien zu durchstöbern und auf dem Mac oder PC zu organisieren. Alle im iTunes Store gekauften Inhalte und alle von CDs importierten Songs werden in Ihrer Mediathek in iTunes angezeigt. Sie können Ihre eigenen oder Genius Wiedergabelisten erstellen, Genius Mixe auswählen und alles mit Ihrem iPod nano synchronisieren. Und iTunes ist als kostenloser Download verfügbar.
 
Der beste Music Store der Welt
Laden Sie Ihre Lieblingssongs auf Ihren iPod nano. Oder stöbern Sie in über 13 Millionen Songs und finden Sie weitere Hits. Sie können nach dem Namen eines Interpreten, Songs oder Albums suchen und so genau die richtigen Songs finden. Sie suchen neue Musik und brauchen Hilfe? Die Genius Seitenleiste empfiehlt Ihnen neue Musik, die auf Ihren Lieblingssongs basiert. Sie können in jeden Song kostenlos 30 Sekunden reinhören. Und mit einem Klick können Sie einen Song kaufen. Er wird dann sofort geladen. Schneller und einfacher können Sie Ihre digitale Musiksammlung für den iPod nicht zusammenstellen.
 
Bedienungshilfen
Integrierte Bedienungshilfen.
iPod nano kommt mit Bedienungshilfen, die Menschen mit Handicaps helfen Musik, Hörbücher und mehr zu erleben.
 
VoiceOver
Der iPod touch bietet VoiceOver, die weltweit erste Bildschirmlesefunktion, die auf Gesten basiert. Tippen Sie auf das Display und Sie hören eine Beschreibung des Objekts, das Sie gerade berühren. Steuern Sie den iPod nano durch Doppeltippen, Bewegen oder Streichen. Mit den optionalen Apple Earphones mit Fernbedienung und Mikrofon können Sie Ihre Musik steuern, ohne auf das Display zu sehen. VoiceOver nennt Ihnen den Song und Interpreten und spricht auch noch 29 Sprachen.
 
Weiß auf Schwarz
Wenn Sie stärkeren Kontrast möchten, stellen Sie das Display des iPod nano so ein, dass Weiß auf Schwarz angezeigt wird. Sie können diese Funktion in jeder App und auch auf dem Homescreen verwenden.
 
Mono Audio
Wenn Sie nur auf einem Ohr gut hören können, können Sie ""Mono-Audio"" aktivieren, damit die Audioausgabe auf beide Ohrhörer geleitet wird und Sie beide Kanäle mit dem gesunden Ohr hören können.

Produktbeschreibungen
 
Highlights
- Multi-Touch Display
- Genius - dein Mixmaster
- FM Radio
- iTunes
- Integrierte Bedienungshilfen (VoiceOver und Weiß auf Schwarz)
 
Akku
- Akkutyp: Li-Ion
- Akkulaufzeit bis zu 24 Stunden
 
Display
- Farbdisplay
- Bilddiagonale: 3,91 cm
- 1,54- Display
- Auflösung Breite: 240 Pixel
- Auflösung Höhe: 240 Pixel
 
Speicher
- Interner Speicher 8.000 MB
 
Stromversorgung
- USB-Lader
 
Wiedergabeformate Audio
- AAC
- MP3
- WAV
 
Grundeigenschaften
- Breite: 40,9 mm
- Höhe: 37,5 mm
- Tiefe: 8,78 mm
- Gewicht: 21,1 g
- Gewicht: 21,1 g
- Farbe: Dunkelgrau
 
Lieferumfang
- iPod nano
- Apple Earphones
-Dock Connector auf USB Kabel
- Dokumentation und wichtige Produktinformationen
";2;False;0;;;Apple iPod Nano 8 GB 6. Gen. verschiedene Farben;apple-ipod-nano-8-gb-6-gen-verschiedene-farben;True;True;PD-01073;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;149.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40652,5607638889;49;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000266-apple-ipod-nano-16-gb-6-gen-verschiedene-farben.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000267-apple-ipod-nano-16-gb-6-gen-verschiedene-farben.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000268-apple-ipod-nano-16-gb-6-gen-verschiedene-farben.jpg;3;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Apple MacBook Air MC966D/A-i7 13,3 Zoll Notebook;"Apple MacBook Air 33,78cm (13,3"") 1,8GHz i7 4GB 256GB SSD";"
Eindrücke:
Bei der Entwicklung des neuen MacBook Air gab’s nur ein Ziel: ein unglaublich dünnes und leichtes Notebook, genauso leistungsstark und vielseitig wie doppelt so große Geräte. Und mit Flash-Speicher,
 
stabilem Unibody-Gehäuse, Multi-Touch und einer ausdauernden
 
Batterie erreicht das MacBook Air nicht nur das Ziel, es ist der neue Standard, wie ein Notebook sein sollte. Perfekt bis ins letzte Detail.
 
Design:
Gerade mal 1,7 cm flach. Aber damit legt das neue MacBook Air die Messlatte sehr hoch - und es macht den Flash-Speicher zum Maßstab. Da Flash-Chips so klein sind, ist das MacBook Air so unglaublich dünn und leicht. Diese Flash-Chips sind Solid-State-Komponenten, sie arbeiten ohne bewegliche Teile. Das macht sie zuverlässig, robust und sehr leise beim Arbeiten. Und da wir sie direkt auf der Hauptplatine platzieren, brauchen sie viel weniger Platz – etwa 90 % weniger, um genau zu sein. Es bleibt mehr Platz für andere wichtige Dinge. Zum Beispiel eine größere Batterie. Damit ist ein Notebook entstanden, das fast nichts wiegt und mit einer Batterieladung stundenlang durchhält. So entsteht echte Mobilität.
 
Umweltverträglichkeit:
Die folgenden Merkmale des MacBook Air tragen zu seiner geringeren Umweltbelastung bei:
 
Frei von bromhaltigen Flammschutzmitteln
Ohne PVC
PVC-freie Netzkabel sind in Australien, Japan, Neuseeland, Nord- und Südamerika, der Schweiz, Taiwan, Thailand und Großbritannien verfügbar.
Hochgradig recyclebares Aluminiumgehäuse
ENERGY STAR 5.2 konform
EPEAT-Bewertung ""Gold""
Das MacBook Air hat in den USA und Kanada von der EPEAT die Bewertung ""Gold"" erhalten.
 
Mitgelieferte Software:
 
OS X Lion
Enthält Mail, Adressbuch, iCal, Mac App Store, iTunes, Safari, Time Machine, FaceTime, Photo Booth, Mission Control, Launchpad, AirDrop, Resume-Funktion, automatisches Sichern, Versionen, Übersicht, Spotlight, QuickTime und mehr.
 
iLife '11
Enthält iPhoto, iMovie und GarageBand.
 
Display:
 
Hochauflösendes 13,3"" Hochglanz-Widescreendisplay mit LED-Hintergrundbeleuchtung (33,78 cm Diagonale), Unterstützung für Millionen Farben
 
Unterstützte Auflösungen:
 
1440 x 900 (nativ), 1280 x 800, 1152 x 720 und 1024 x 640 Pixel bei einem Seitenverhältnis von 16:10, 1024 x 768 und 800 x 600 Pixel bei einem Seitenverhältnis von 4:3
";2;False;0;;;Apple MacBook Air MC966D/A-i7 13,3 Zoll Notebook;apple-macbook-air-mc966da-i7-133-zoll-notebook;True;True;P-0720;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;1599.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40652,0359953704;4;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000465-apple-macbook-air-mc966da-i7-133-zoll-notebook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000466-apple-macbook-air-mc966da-i7-133-zoll-notebook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000467-apple-macbook-air-mc966da-i7-133-zoll-notebook.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Samsung Galaxy S II (i9100) DualCore Smartphone weiß;Samsung Galaxy S II (i9100) DualCore Smartphone (10.9 cm (4.3 Zoll) Super-Amoled Plus Display, Android 2.3, 8 MP Full-HD Kamera, 2 MP Frontkamera) weiß;"
Samsung launcht mit dem Galaxy S II den Nachfolger des Bestsellers Galaxy S. Das Galaxy S II ist nicht nur das schlankste (8,49 mm), sondern dank des 1,2 GHz Dual-Core Prozessors auch das schnellste Smartphone seiner Klasse. Darüber hinaus besticht es durch ein 4,3"" Super Amoled Plus Touch-Display. Das Galaxy S II verwendet als Betriebssystem die aktuellste Android 2.3 Version – auch bekannt unter dem Namen Gingerbread. Die integrierte 8 Megapixel Kamera mit LED Blitz hält die schönsten Momente in erstklassiger Qualität fest – darüber hinaus ermöglicht die 2 Megapixel Frontkamera Video Telefonate in beeindruckender Qualität. Das Schreiben von E-Mails und SMS gelingt unkompliziert dank Swype®-Texteingabe. Zahlreiche aktuelle und nützliche Apps stehen im Android Market™ zum Download bereit. Die integrierte Google Maps Navigation™ führt ans gewünschte Ziel. AllShare, HD Video, Exchange ActiveSync und eine Vielzahl an weiteren Applikationen lassen keine Wünsche offen. Ein erstklassiges Zusammenspiel von Hardware und Funktionen leistet sein Übriges für ein ausgezeichnetes Nutzererlebnis auf höchstem Niveau!
 
4,27-Zoll SUPER AMOLED Plus
Bekennen Sie Farbe! Dieses brillante Display bietet den besten Farbumfang, ein hohes Kontrastverhältnis sowie ultimative Schärfe bei Bildern. Die bahnbrechende Verkürzung der Video-Reaktionszeit sorgt für ruckfreie Videowiedergabe. Die neue Technologie benötigt weniger Platz und Energie: Im Vergleich zum Vorgänger benötigt das Display 18% weniger Energie. Es ist damit eines der dünnsten, langlebigsten Smartphones am Markt.
 
Brillante Performance
Das Unmögliche ist möglich. Der Samsung Dual Core Application Prozessor ist die reaktionsschnelle Antwort im Bereich mobile Performance. Er bietet Multitasking in Hochgeschwindigkeit, schnelles Laden von Internetseiten, schnelle Reaktionszeiten, eine intuitive Benutzeroberfläche, blitzschnelle Bildbearbeitung und Spiele mit hoher Performance. Und mit der superschnellen Möglichkeit zum Encodieren und Decodieren, die alles im Bereich Videoaufzeichnung und -wiedergabe (1080p / 30fps) unterstützt, stellt er alle anderen Dual Core-Prozessoren in den Schatten. Problemloses Video- oder Musik-Streaming bekommt dank des schnellen Drahtlosstandards HSPA 21 Mbps einen großen Schub. Hervorragende Rechenleistung, herausstechende Performance.
 
Schlankes Design
Schlank, schlanker, GALAXY S II. Das Samsung GALAXY S II führt die Riege an – mit nur 8,49 mm und einem luxuriösen Design liegt es zudem gut in der Hand. Das GALAXY S II ist eines der schlanksten Smartphones und bietet außerdem HyperSkin für einen schönen Metall-Look mit einer fingerabdruckfreien und rutschfesten Akkuabdeckung.
 
Readers Hub
Lassen Sie Ihre Bücher zu Hause: Das Samsung GALAXY S II übernimmt diese Aufgabe. Stöbern Sie im Readers Hub in Ihrer Bücherei mit Klassikern oder suchen Sie in mehr als 2 Millionen Büchern die neusten Bestseller. Sie können auch 2.500 Magazine in 20 Sprachen und 1.600 Zeitungen in 47 Sprachen zur Lieferung einrichten. Mit klarem, deutlichem Text und der hohen Bedienerfreundlichkeit macht das Lesen Spaß: vergrößern, nur Text und Seitenansichten, Audiozugriff sowie schnelles Verteilen per E-Mail sind nur einige Funktionen. Glauben Sie an Bücher, beschränken Sie sich jedoch nicht nur auf Papier.
 
8-Megapixel-Kamera mit LED-Blitz
Immer gute Fotos. Der 8-Megapixel-Kamera mit Autofokus entgehen auch bei Action-Fotos keine Details. Machen Sie auch bei schlechten Lichtverhältnissen mit dem integrierten LED-Blitz wunderschöne und detaillierte Aufnahmen. Und dank der stark verbesserten Benutzeroberfläche von Android Gingerbread ist selbst schneller Szenenwechsel möglich. Wechseln Sie problemlos auf die 2-Megapixel-Kamera vorne, um Selbstporträts zu machen. Einfach immer gute Bilder.
 
Aufzeichnung & Wiedergabe in Full-HD
Werden Sie zum Star. Mit den Möglichkeiten zur Videoaufzeichnung des Samsung GALAXY S II können auch Sie zur Berühmtheit werden. Mit der 1080p Full-HD-Aufzeichnung ist jeder Moment ein potenzielles Meisterwerk in der Entstehung. Erfassen Sie die Action in hoher Auflösung und mit Dual Core-Geschwindigkeit und geben Sie Ihre HD-Aufzeichnungen mit bestechender Klarheit auf dem 4,3"" SUPER AMOLED Plus Display wieder.
 
Spracherkennung & Sprachübersetzung
Einfach Sprachbefehle nutzen. Tippen Sie nur doppelt auf die Home-Taste und steuern Sie das Samsung GALAXY S II mit ausgewählten Sprachbefehlen. Führen Sie wichtige Funktionen wie anrufen, Musik hören oder SMS schreiben mit einfachen Sprachbefehlen aus. Sie können auch Ihre Gedanken festhalten, sich selbst eine Notiz schreiben oder unterwegs sogar mit Google Voice Translation eine Übersetzung anfertigen. Galaxy S II kann Ihnen eingehende Nachrichten auch vorlesen.
 
Game Hub
Noch mehr Spielspaß. Über den Game Hub von Samsung GALAXY S II können Sie hochwertige Spiele herunterladen: 12 soziale Netzwerkspiele und 13 Prämiumspiele einschließlich Gameloft’s Let Golf 2 und Real Football 2011. Sie können nach Spielen und Informationen zu Neuerscheinungen suchen oder einfach nur spielen. Mit einem Beschleunigungsaufnehmer, einem magnetischen Sensor und Gyroskop-Sensor heben sich Spiele mit Hand- und Armbewegungen deutlich aus der Masse ab. Die kleinste Bewegung reicht bereits aus – das ist spannende Unterhaltung.
 
Social Hub
Mit dem Social Hub lassen sich Ihre Online-Kontakte besser organisieren und synchronisieren. Sammeln Sie Ihre Informationen aus E-Mails, SMS, IM und SNS in einem einheitlichen Posteingang – Interaktionen mit anderen sind so schneller und auf die von Ihnen gewünschte Art möglich.
 
Music Hub
Musik darf nicht fehlen. Der neue native Music-Player von Samsung bietet ein intuitives Wiedergabesystem zum Suchen, Entdecken, Anspielen, Kaufen und Herunterladen von Musikstücken für unterwegs. Die App bietet auch viele Informationen zum Kauf sowie Zugriff auf alle gewünschten Künstler, Liedtexte und Bewertungen. Sie können Empfehlungen für neue Songs abrufen und durch Bassverstärkung und 5.1 Kanal-Sound den Hörspaß noch mehr steigern.
 
Microsoft Exchange ActiveSync
Das Samsung GALAXY S II ist für sicheren Zugriff auf Unternehmensressourcen auf einem Microsoft Exchange Server optimiert, damit Sie in Bezug auf geschäftliche E-Mails, Terminplaner, Kontakte und Aufgabensynchronisation auf dem Laufenden sind. Das Handy bietet die umfangreichste mobile Implementierung von Exchange ActiveSync. Es bietet das sicherste Mobile Device Management unter den Smartphones und unterstützt die meisten Richtlinien und Einschränkungen unter den Android ActiveSync Clients und ermöglicht Kommunikation in Echtzeit mit Telefonen der Mitarbeiter, um Einstellungen per Fernzugriff zu konfigurieren, die Einhaltung der Richtlinien zu überwachen, die Sicherheit bei synchronisierten Daten zu gewährleisten und verwaltete Telefone zu sperren oder Daten zu löschen.
";2;False;0;;;Samsung Galaxy S II (i9100) DualCore Smartphone weiß;samsung-galaxy-s-ii-i9100-dualcore-smartphone-weiss;True;False;P-0020;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;439.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40651,9089699074;76;5;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000473-samsung-galaxy-s-ii-i9100-dualcore-smartphone-weis.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000474-samsung-galaxy-s-ii-i9100-dualcore-smartphone-weis.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000475-samsung-galaxy-s-ii-i9100-dualcore-smartphone-weis.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;HTC Hero;"HTC Hero ";"
HTC Hero Smartphone ohne Vertrag, ohne Branding, kein Simlock
Probiere etwas Neues. Sei Du selbst.
 
Der HTC Hero bietet Dir das ultimative HTC-Erlebnis. Du kannst dieses Smartphone wie kein anderes an Deine individuellen Bedürfnisse anpassen und machst es dadurch zu einem Mobiltelefon, das wie für Dich geschaffen ist. Es verbindet Dich leichter denn je mit den Menschen, die für Dich wichtig sind. - Denn alle Kommunikationen werden nach Personen anstatt nach Anwendungen organisiert. Der HTC Hero wird Dir - egal wo Du gerade bist und was Du gerade machst - das Leben durch seine einfache und intuitive Bedienung erleichtern. So, wie Du es Dir von Deinem Handy immer gewünscht hast!
 
Make it your Hero
Der HTC Hero ermöglicht Dir einen Level der Personalisierung, den kein anderes Smartphone bislang geboten hat. Anstatt wichtige Anwendungen hinter zahlreichen Menüstrukturen zu verstecken, kannst Du sie nun dort positionieren, wo Du direkten Zugriff hast: nämlich direkt auf einem der 7-teiligen Homescreens! Und weil HTC an die absolute Personalisierung glaubt, kannst Du auch viele Widgets mit vielfältigen Designs und in verschiedener Größe anpassen, ganz nach Deinem Geschmack. Das interaktive Erlebnis geht weiter, wenn Du z.B. einen Aktien-Ticker auf den Homescreen legst oder Dir die aktuelle Wettervorhersage für heute oder auch gleich für die nächsten fünf Tage auf einen Blick anzeigen lässt.
 
Stay close with friends
Die vernetzte Welt bietet uns zwar die Möglichkeit, mit mehr Menschen als jemals zuvor in Kontakt zu bleiben, aber den Überblick über alle Kontakte zu behalten, wird immer schwieriger. Statt umständlich eine Anwendung nach der anderen zu öffnen, um Deine Freunde zu kontaktieren, funktioniert das mit dem HTC Hero einfacher: Wenn Du Deine Kontakte aufrufst, siehst Du auf einen Blick die verschiedenen Möglichkeiten der Kontaktaufnahme und alle bisherigen Interaktionen - einschließlich der E-Mails, die Du an Deine privaten und beruflichen E-Mail-Adressen erhalten hast. Außerdem kannst Du direkt Status-Updates in Deinen Social Communities verfolgen und Dir die neuesten Fotos ansehen, die Deine Freunde gerade hochgeladen haben.
 
Discover the Unexpected
Selbst grundlegende Dinge wie die Anruf-Funktion werden Dich beim HTC Hero angenehm überraschen. Denn Du findest eine Person, indem Du ihre Telefonnummer wählst oder einfach nur die ersten Buchstaben ihres Namens eingibst. Und während Du in der Kontakt-Ansicht bist, kannst Du auch gleich einmal nachsehen, ob Dein Kontakt bald Geburtstag hat oder neue Infos oder Bilder auf Facebook oder Flickr eingestellt hat.
 
Mit dem HTC Hero kannst Du Deine Inhalte immer aus der Perspektive betrachten, die Dir gerade am besten passt. Deine Inbox ist zum Beispiel nicht nur eine Liste mit E-Mails, sondern vielmehr ein Konversations-Chat. Mails mit Anhängen kannst Du in einer separaten Dokumenten-Bibliothek ansehen. Die Fotos in Deinem Fotoalbum sind nicht nur auf Deinem Handy abgespeichert, sondern Du kannst sie via Upload auf Facebook oder Flickr auch mit Deinen Freunden teilen.
 
Suche und finde einfach alles, überall – mit Deinem HTC Hero. Anhand des Such-Buttons durchsuchst Du Tweets in Twitter, findest Personen in Deiner Kontaktliste, suchst nach E-Mails in Deinem Posteingang oder Terminen in Deinem Kalender… und selbst die sprichwörtliche Suche nach der Nadel im Heuhaufen ist so von Erfolg gekrönt.
 
 
";2;False;0;;;HTC Hero weiß;htc-hero;True;True;P-0015;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;449.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40651,7809027778;"73;2095";36;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000344-htc-hero.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000345-htc-hero.jpg;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;LG KM 900 Arena;LG KM 900 Arena;"LG KM 900 Arena
 
FM Transmitter, GPS, 5MP,WLAN 
 

brilliantes, hochauflösendes 3Zoll Touchscreen
benutzerfreundliches S-Class User Interface durch taktiles Feedback bei Tastendruck & Widgets
Dolby Mobile Surround Sound und FM Transmitter für ein einzigartiges Musikerlebnis
FM-Radio mit Senderspeicher und FMTransmitter
Lieferumfang: Gerät, Akku, Ladegerät, stereo Kabel, Headset, Bedienungsanleitung, USB Datenkabel, PC-Software ";2;False;0;;;LG KM900 Arena;lg-km-900-arena;True;True;P-0026;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;219.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40651,7531597222;"72;2095";19;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000233-lg-km-900-arena.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000234-lg-km-900-arena.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000235-lg-km-900-arena.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;HTC Touch Diamond 2;HTC Touch Diamond 2;"
HTC Touch Diamond II
 
Brillantes Design und intuitive Bedienung sorgen schon beim ersten Ausprobieren für ein faszinierendes Erlebnis.
Der HTC Touch Diamond2 liefert ein komplett neues Erlebnis mobiler Kommunikation, das die Interaktionsfähigkeit mit anderen Menschen spürbar vereinfacht.
 
In Kombination mit der neuen TouchFLO™ 3D-Oberfläche ist der HTC Touch Diamond2 das aktuell attraktivste Smartphone für Konsumenten, die auf Design und Funktion setzen.
 
Erstmals präsentiert HTC einen personenzentrischen Kommunikationsansatz: Zu jeder Kontaktperson steht die gesamte Konversationshistorie auf einen Fingerstreich zur Verfügung, unabhängig von der Art der Kommunikation wie Sprache, Text oder E-Mail.
 
Features
 
5-Megapixel-Kamera mit Autofokus
Erweitertes TouchFLO 3D für eine bessere intuitive Nutzung
3,2” WVGA LCD Touchscreen mit 480x800 Pixeln
Zoom-Leiste für präzises Hinein- und Heraus- Zoomen in Bildern, Webseiten oder Google Maps™
microSD™ (SD 2.0-kompatibel) Erweiterungs-Slot 
 
Mehr als ein Telefongespräch
In der heutigen Zeit gibt es viele verschiedene Arten der Kommunikation, doch sie haben alle etwas gemeinsam: Am anderen Ende befindet sich immer eine Person. Aus diesem Grund ermöglicht Ihnen der HTC Touch Diamond2, Ihre Kommunikation nach Personen zu organisieren – nicht nur nach der Art wie Sie kommunizieren.
 
In Ihren Kontakten befindet sich Ihre gesamte Kommunikations-Historie – egal ob E-Mail, SMS oder Telefongespräch. Es spielt keine Rolle, ob Sie während eines Gesprächs nach einer E-Mail gefragt werden oder Sie in einem Café sitzend einen Text abrufen möchten – alle Interaktionen sind nach Personen geordnet in einem Kommunikationsbaum abgelegt.
 
Erweitern Sie Ihr Blickfeld
Eine unbestrittene Tatsache bei Smartphones – ein großer Bildschirm bei einem kleinen Gerät, das ist gut. Genau darum haben wir das Display des Touch Diamond2 so groß wie möglich designt, bei gleichbleibend kompaktem Gehäuse. Genießen Sie Videos, Webseiten, Fotos und andere Abbildungen auf dem ultra-scharfen Widescreen-Display – es lässt auch das kleinste Detail erkennen. 
Schön und leistungsfähig zugleich
Das Mobiltelefon ist eines der wenigen Gegenstände, die wir heutzutage immer an unserer Seite haben. Es hilft uns nicht nur mit unseren Freunden, Geschäftspartnern und dem weltweiten Geschehen verbunden zu sein – es ergänzt uns. Der Touch Diamond2 ist Ihr perfekter Begleiter: Er hält Sie auf dem Laufenden und ist stilvolles Accessoire zugleich.
Mit seinem klaren und doch elegantem Design ist das HTC Touch Diamond 2 ein Smartphone mit Stil und Eleganz. Seine einfache Handhabung über den TouchFlo-3D- Bildschirm überzeugt. Feinste Sensoren garantieren eine empfindliche, daher schnelle Bedienbarkeit. Ein neues Erlebnis von mobiler Kommunikation ob im privaten oder im business-Bereich.
 
Die zahlreichen Funktionen sind komfortabel zu bedienen, die ausgeprägte Technik im HTC Touch Diamond 2 vereint zahlreiche Funktionen mit wenig Aufwand. Als Navigationsgerät ein zuverlässiger Wegweiser ist das HTC Touch Diamond 2 ein edler Begleiter, nicht zuletzt durch die zahlreichen Onlinefunktionen für Unterwegs der ideale Communicator.
 
";2;False;0;;;HTC Touch Diamond 2 Smartphone;htc-touch-diamond-2;True;True;P-0012;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;399.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40651,7106365741;73;36;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000198-htc-touch-diamond-2.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000199-htc-touch-diamond-2.jpg;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;HTC Touch HD;HTC Touch HD;"
HTC Touch HD (Blackstone) (UMTS, HSDPA, 5MP, Touch Screen, 3.8 Zoll Display) Smartphone ohne Branding
 
HTC – Smarte Geräte für smarte Leute / Perfekt für Sie geeignet
Bei der Entwicklung von HTC-Produkten berücksichtigen wir immer die Bedürfnisse individueller Anwender. Wenn Sie gerne Text eintippen, gibt es für Sie Geräte mit praktischen aufschiebbaren QWERTZ-Tastaturen. Mit einem unserer vielen Touch-Geräte können Sie entweder mit Ihren Fingern oder einem Stift Anwendungen bedienen und im Internet browsen. Wenn Sie sich eine hohe Leistungsfähigkeit wünschen, geben Ihnen unsere 3,5G-Geräte die Geschwindigkeit, die Sie für das Herunterladen und Streaming von Medieninhalt aus dem Internet benötigen. Wenn Sie nach einem Telefon suchen, das einfach alles kann, finden Sie in unserem Produktsortiment leistungsfähige PDA-Telefone, die Ihnen alle möglichen Funktionen für unterwegs bieten. Die Liste kann unaufhörlich fortgesetzt werden.
 
HTC glaubt nicht, dass es lediglich eine große Lösung für alle Probleme gibt. Warum sollten Sie Ihre Lebensweise auf die Funktionen eines einzelnen Produktes abstimmen? Egal welche Bedürfnisse Sie haben, mit unserer jahrelangen Erfahrung in Innovation, unserem Fachwissen und unserem Vorstellungsvermögen kann HTC Ihnen mit Sicherheit Produkte bieten, die perfekt auf Sie und Ihren Lebensstil zugeschnitten sind.
 
Führende Technologie
HTC ist ein Vorreiter in der Technologie für mobile Geräte. Wir entwickeln nicht nur Produkte mit Funktionen, die Sie haben sollten, wir entwickeln Produkte mit Funktionen, die Sie wirklich benötigen, und die Sie sich wirklich wünschen. Wir wissen, dass Sie sich ein schickes und smartes Gerät wünschen, mit dem Sie Ihre Arbeiten erledigen können, mit denen Sie jederzeit erreichbar sind und mit denen Sie auch mal etwas Spaß haben können. Dies ist der Grund dafür, warum HTC immer wieder neue Maßstäbe bei der Herstellung von Produkten setzt, die Kunden das bestmögliche mobile Erlebnis bieten können.
 
HTC hört Ihnen zu
HTC produziert Produkte, die Ihnen, unserem geschätzten Kunden, gefallen. Um dies auch wirklich zu erreichen, legen wir sehr viel Wert darauf, Ihnen zuzuhören und herauszufinden, wie Sie Ihr Leben gestalten und welche Wünsche Sie haben. Wir verfolgen nicht nur die Trends auf dem Markt sondern auch die Entwicklungen im kulturellen Umfeld. Wir nehmen uns die Bedürfnisse unserer Kunden zu Herzen und entwickeln auf effiziente Weise neue Produkte, um Ihre Wünsche in kürzester Zeit zu erfüllen.
 
Das HTC Touch HD im Detail
Genießen Sie Musikvideos, Filme und Streams, wie Sie es sich nie auf einem Mobilgerät erträumt hätten. Das Surfen im Internet wird zu einer berauschenden Erfahrung ... so als hätten Sie Ihren Laptop dabei. Und das alles auf einem hochauflösenden 3,8""-WVGA-Display, das sich nahtlos mit der berührungsempfindlichen TouchFLOTM 3D-Oberfläche vereint.
 
Dank der blitzschnellen 3.5G-Technologie erreicht Ihre Internetverbindung echte Breitbandgeschwindigkeit. In HSDPA-Netzen liefert das Touch HDTM eine Downloadgeschwindigkeit von bis zu 7,2 Mbit/s – so können Sie ohne Einschränkungen arbeiten und spielen.
 
Das neue Register „Stock“ (Aktien) informiert über aktuelle Aktienkurse, während in der Startanzeige E-Mails, Nachrichten und der Kalender nur einen Fingerzeig entfernt sind.
 
Die Routenführung bringt Sie sicher ans Ziel, Satellitenkarten weisen Ihnen den Weg und mit GoogleTM Maps wissen Sie jederzeit, wo Sie gerade sind. Auf dem breiten Display sind die Karten jetzt noch größer und schärfer. Die Anzeigesteuerung bietet eine Zoomfunktion und eine Detailansicht. So wird Navigation völlig neu definiert.
 
Zu den Highlights des Gerätes gehören:
- Kinoerlebnis für unterwegs mit 3,8 Zoll breitem WVGA-Display (480 X 800 Pixel)
- Fortschrittliche TouchFLOTM 3D -Oberfläche, die beim Navigieren durch Kontakte und Webseiten sowie Anzeigen von 
  Medieninhalten perfekt auf Fingerbewegungen reagiert
- HSDPA-Internetverbindung ermöglicht Surfen und Datentransfer mit Breitbandgeschwindigkeit.
- Google MapsTM im Breitbildformat
- 5-Megapixel-Kamera für höchste Foto- und Videoqualität
- Durch den 3,5-mm-Audioanschluss ist das Touch HDTM mit umfangreichen Audiozubehör kompatibel.
 
";2;False;0;;;HTC Touch HD Smartphone;htc-touch-hd;True;True;P-0009;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;449.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40651,6773263889;73;36;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000188-htc-touch-hd.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000189-htc-touch-hd.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000190-htc-touch-hd.jpg;1;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Sony Ericsson Xperia PLAY Smartphone;Sony Ericsson Xperia PLAY Smartphone (10,1 cm (4 Zoll) Touchscreen, 5 MP Kamera, Android OS 2.3, inkl. 7 vorinstallierten Spielen);"
Sony Ericsson Xperia PLAY
Effizientes Arbeiten und hochklassiges Spielevergnügen
Sie brauchen ein hocheffizientes, voll ausgestattetes Smartphone? Und was wäre, wenn es noch richtige Spielsteuerungselemente bieten würde? Hier ist es: Das Xperia™ PLAY. Ein PlayStation™ certified Android™ Smartphone, das Sie in die Spiele Ihrer Wahl eintauchen lassen.
 
Vorinstallierte Spiele
Auf dem Xperia™ PLAY haben Sie viele Spiele vorinstalliert, mit denen Sie Ihr Können unter Beweis stellen können. Und das ist nur der Anfang. Wählen Sie aus einem riesigen Angebot, das ständig wächst und bereits Tausende von Spielen der weltbesten Anbieter umfasst, unter anderem auch PlayStation®-Spiele. Besuchen Sie den Android Market™ und schauen SIe nach, welche Anbieter bereits Spiele bereitgestellt haben. (Vorinstalliert sind folgende Spiele: Star Battalion, Bruce Lee: Dragon Warrior, Crash Bandicoot, FIFA10, SIMS 3, Tetris)
 
Das Xperia PLAY™ ist in aller Munde. Das erste PlayStation®-zertifizierte Smartphone löst wahre Begeisterungsstürme bei den Spieleanbietern aus.
 
So, das ist nun das PSP Handy?
Einst ein Traum. Heute Realität. Das erste PlayStation certified Android™-Smartphone bietet eine unglaubliche Grafik, eine großartige Tonqualität und richtige Spielsteuerungselemente. Das Handy wird dennoch nicht ""das PSP Handy"" genannt. Wir nennen es Xperia™ PLAY.
 
Das Smartphone als Controller
Spielbegeisterte erkennen sofort die Konsolentasten. Sie wurden von demselben Team entwickelt und getestet, das auch den PS3-Controller entwickelt hat.
 
Das erste PlayStation®-zertifizierte Smartphone mit speziellen Spieletasten, L/R-Schultertasten und vier Symboltasten
4-Zoll-Multitouch-Bildschirm mit 16 Millionen Farben
Spielvergnügen wie bei einer Spielekonsole mit überragendem Stereo-Sound
Mit Snapdragon 1-GHz-CPU und dem leistungsstarken Grafikprozessor Adreno 205, der optimales Spielvergnügen garantiert
Micro SD mit 8 GB (im Lieferumfang enthalten), erweiterbar auf 32 GB
 
Multimedia-Smartphone mit Android™
Nie wieder verlaufen. Entdecken Sie Städte und Sehenswürdigkeiten mit 3D-Karten. Verwenden Sie Google Voice Search™, um Anrufe zu tätigen, Nachrichten zu schreiben usw. Mit Ihrem Xperia™ PLAY Android™ Handy brauchen Sie nicht mehr zu tippen. Geben Sie die Anweisungen einfach per Sprache ein. Darf's etwas mehr sein? Holen Sie sich alle Apps, die Sie brauchen, aus dem Android Market™.
 
Greife direkt auf die mobilen Dienste von Google™
Surfe per Sprachbefehl mit Google Voice Search™ im Internet
Mach aus deinem Smartphone im Handumdrehen eine Spielekonsole
";2;False;0;;;Sony Ericsson Xperia PLAY Smartphone;sony-ericsson-xperia-play-smartphone;True;True;P-0028;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;269.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40651,6637268519;77;35;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000573-sony-ericsson-xperia-play-smartphone.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000574-sony-ericsson-xperia-play-smartphone.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000575-sony-ericsson-xperia-play-smartphone.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;LG P970 Optimus Black Smartphone;"LG P970 Optimus Black Smartphone (10.2cm (4 Zoll) NOVA-Touchscreen, 5 MP Kamera, 9.2mm dünn, Android 2.2, 3.5mm Buchse, Wifi, GPS) schwarz ";"
Die Superlative - LG P970 Optimus Black mit NOVA Display Technologie
Neue Technologie für helles und gleichzeitig energiesparendes Display
10.2 cm (4 Zoll) Touchscreen Smartphone mit Android 2.2 Betriebssystem, 2 Megapixel Frontkamera, WiFi (b/g/n standards).
 
Superflach, superhell und super energiesparend: Das neue Android-Modell LG P970 OPTIMUS BLACK steht für eine neue Form der Superlative bei Smartphones. Das NOVA-Display mit einer Bildschirmdiagonale von 10,2 Zentimetern garantiert die hellste, klarste und deutlichste Anzeige auf einem Mobiltelefon-Display — selbst bei direkter Sonneneinstrahlung. Einen Superlativ bringt LG auch mit dem Design des neuen Android-Modells: Mit nur 9,2 Millimetern ist das LG P970 OPTIMUS BLACK eines der dünnsten Smartphones auf dem Markt.
 
LG’s NOVA-Technologie — ein Display-Novum in Sachen Helligkeit…
„Unser LG P970 OPTIMUS BLACK ist der Inbegriff des innovativen Smartphones. Die Kombination aus anspruchsvoller Technologie sowohl beim Display als auch beim Design machen unser neues Android-Modell zu einem absoluten Must-Have“, so Gunter Thiel, Head of Mobile Marketing bei der LG Electronics Deutschland GmbH.
Mit einer Leuchtdichte von 700cd/m² (Candela pro Quadratmeter) setzt das NOVA-Display neue Standards: Sehr gute Smartphones-Displays kommen aktuell auf bis zu 480 cd/m². Dank seiner größeren Helligkeit und reinen Weißtönen, die eine kontrastreiche Schwarz-Weiß-Darstellung ermöglichen, bietet das neue Smartphone den Anwendern mehr Komfort beim Surfen im Internet, Lesen von E-Mails und Verfassen von Dokumenten.
 
… und im Stromverbrauch
Das NOVA-Display zeigt auch seine „grüne“ Seite: Es verfügt nicht nur über eine höhere Leuchtkraft, sondern sorgt darüber hinaus für eine deutliche Reduzierung des Energieverbrauchs. Im Vergleich zu einer herkömmlichen LCD-Anzeige benötigt das Display 50 Prozent weniger Strom. Auch AMOLEDs verbrauchen doppelt so viel Energie wie ein NOVA-Display für die Darstellung eines hauptsächlich weißen Bildschirms, also des Farbschemas, das am häufigsten beim Browsen im Web genutzt wird. In Verbindung mit dem 1500-mAh-Akku des LG P970 OPTIMUS BLACK steht den Nutzern genügend Energie für ihre täglichen Anforderungen selbst bei maximaler Helligkeitseinstellung zur Verfügung.
 
Superlative auch in Sachen Style …
Dank seinem ultraflachen 9,2 Millimetern Design setzt das LG P970 OPTIMUS BLACK mehr als nur stylishe Akzente: Mit einem Gewicht von gerade mal 109 Gramm, einer eleganten Linienführung und abgerundeten Kanten wird das neue Smartphone zu einem wahren Handschmeichler. Mit der raffinierten Rückseite des Geräts, die nach Außen flach zuläuft, wirkt das Profil von 6,0 Millimetern noch einmal schlanker. Ein unverwechselbares Kennzeichen des LG P970 OPTIMUS BLACK ist das minimalistische Design — selbst der Lautsprecher ist nahezu unsichtbar im Rahmen des Telefons integriert.
 
… und Funktionen: Wi-Fi Direct, Apps und vieles mehr
Als weltweit erste Gerät unterstützt das LG P970 OPTIMUS BLACK Wi-Fi Direct1 für die schnelle Übertragung von Daten zu anderen Geräten. Zudem bietet das neue Android-Smartphone eine Reihe von intelligenten Funktionen für den einfachen und schnelleren Zugriff auf relevante Apps und Inhalte. Das OPTIMUS User Interface (UI) 2.0 ermöglicht den Anwendern den direkten Zugriff auf Nachrichten, E-Mails und verpasste Anrufe mit nur einer Fingerberührung auf dem gesperrten Display. Die Gestensteuerung unterstützt auch intuitive Kommandos wie Hochheben, Schütteln und Antippen, um Anrufe entgegenzunehmen, in den Kameramodus zu schalten oder Musik zu genießen. Ebenfalls ein Novum ist die Ausstattung mit einer Frontkamera mit 2 Megapixeln Auflösung.
(1Für die Aktivierung von Wi-Fi Direct™ auf dem Smartphone ist eine Anwendung erforderlich, die in der erste Hälfte des Jahres 2011 im Android Market zum Download zur Verfügung gestellt wird.)
 
Alle Features des LG P970 OPTIMUS BLACK sind auf der Android 2.2 Froyo Plattform mit der Möglichkeit zum zukünftigen Upgrade auf Android 2.3 Gingerbread verfügbar. Nach einem Upgrade auf Android Gingerbread können die Nutzer Videogespräche mit höherer Qualität über die 2- Megapixel-Frontkamera des LG P970 OPTIMUS BLACK führen.
 
Beschreibung der Features
 
2 MP Front-Kamera
Warum auf Bildqualität für sich selbst verzichten? Mit der 2 MP Front-Kamera haben Sie jetzt eine noch höhere Auflösung für die Front-Kamera zur Verfügung. Für Selbstporträts und Videotelefonie in noch höherer Qualität.
 
Volle Flash-Unterstützung und Android Market
Dank des Android Betriebssystems haben Sie uneingeschränkten mobilen Zugriff auf das Internet. Ihr Smartphone unterstützt sämtliche Flash-Formate und setzt dem Online-Spaß keine Grenzen. Ausserdem haben Sie die Möglichkeit, auf Apps zuzugreifen und können Sich beispielsweise den Google Navigator kostenlos herunterladen. So haben Sie ein Navigationsgerät in Ihrem Handy.
 
Im gigantischen Online Store Android Market stöbern Sie vom Handy aus durch über 200.000 Apps für Social Networks, Games, Lifestyle, Shopping und mehr. Oder Sie finden genau die App, die Sie schon lange gesucht haben. So individualisieren Sie Ihr Smartphone genau nach Ihren Wünschen und machen Ihren neuen Begleiter zu einem Spezialisten auf jedem Gebiet.
 
G-Key
Mit dem G-Key bedienen Sie Ihr Smartphone noch intuitiver. Bei aktiviertem G-Key nehmen Sie eingehende Anrufe mit einer einfachen Bewegung ihres LG an, scrollen zwischen Fotos oder wechseln Anwendungen wörtlich im Handumdrehen.
 
NOVA Display
Mit einem NOVA-Display müssen Sie nie wieder nach einem schattigen Platz suchen, um etwas erkennen zu können. Ob in völliger Dunkelheit oder direkter Sonneneinstrahlung, das NOVA Display bietet Ihnen jederzeit perfekte Klarheit und eine ungekannte Farbechtheit. Es ist dabei bis zu 50% energieeffizienter als vergleichbare LCD-Displays.
 
Wi-Fi Direct
Mit der Wi-Fi Direct Technik übertragen Sie Daten zwischen Wi-Fi-Geräten ganz simpel und schnell, ohne einen externen Acces Point zu benötigen. Wi-Fi Direct zeichnet sich dabei nicht nur durch die einfache Bedienung sondern darüber hinaus auch durch die extrem hohe Übertragungsrate aus: 20 mal schneller als über eine herkömmliche Bluetooth-Verbindung.
";2;False;0;;;LG P970 Optimus Black Smartphone;lg-p970-optimus-black-smartphone;True;True;P-0023;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;189.0000;189.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40651,6470023148;"72;2095";19;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000259-lg-p970-optimus-black-smartphone.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000260-lg-p970-optimus-black-smartphone.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000261-lg-p970-optimus-black-smartphone.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Motorola Milestone 2 Smartphone;Motorola Milestone 2 Smartphone (9,4 cm (3,7 Zoll) Touch-Display, 5 Megapixel Kamera, 1Ghz, 16GB, Android 2.2);"
Motorola Milestone 2 - Slider Smartphone mit QWERTZ Tastatur (9,4 cm (3,7 Zoll) Touch-Display, 5 Megapixel Kamera, 1Ghz, 16GB, Android 2.2)
 
Motorola Milestone 2 - Ansichten
MILESTONE™ 2 mit MOTOBLUR™
Das ultraflache Slider - Smartphone mit Android™ 2.2 und ausklappbarer QWERTZ-Tastatur bietet im Vergleich zu seinem Vorgänger noch mehr Geschwindigkeit, noch mehr Verbindungsmöglichkeiten, noch mehr Messaging, noch mehr Speicher, noch mehr Web-Erlebnisse, noch mehr Multimedia, den Adobe® Flash®-Player 10.1 und ein Plus an Personalisierung.
 
Das Hochleistungs-Smartphone besitzt einen 1 GHz-Prozessor, der alle Eingaben blitzschnell umsetzt, selbst wenn viele Anwendungen parallel laufen oder eine Vielzahl von Webseiten geöffnet sind. E-Mails oder Nachrichten lassen sich dank verbesserter QWERTZ-Tastatur mit noch größeren Tasten und sehr gutem Tastendruck schneller eingeben. MILESTONE 2 ist bestens auf die Anbindung an das firmeneigene IT-Netz eingestellt. Zusätzliche Kontrollmöglichkeiten erhöhen die Sicherheit in Firmennetzwerken. Das Smartphone lässt sich außerdem als persönlicher WLAN-Hotspot einsetzen, über den sich bis zu fünf Nutzer mit ihren Geräten im Internet einloggen können.
 
MOTOBLUR synchronisiert DatenMOTOBLUR™ erleben
 
Das MILESTONE 2 ist mit der neuesten MOTOBLUR-Version, Motorolas mobilem Dienst für soziale Netzwerke, ausgestattet.
MOTOBLUR fasst alle verfolgten Threads, Freunde und freigegebene Posts, Links oder Fotos in einem einzigen Datenstrom zusammen.
MOTOBLUR synchronisiert Daten von Gmail, Arbeits-E-Mails, Facebook, Myspace und Twitter. Dabei werden Ihre Daten sogar gesichert, d. h. Sie können auch bei einem Verlust des Telefons die Informationen auf einem neuen Telefon von Motorola mit MOTOBLUR wiederherstellen, wenn Sie Ihren Benutzernamen und ein Kennwort eingeben.
 
 
Fotos und VideosBilder und Videosequenzen in großartiger Qualität

Die 5-MP-Kamera mit Zoom, Autofokus, Blitzlicht und Bildstabilisation ist ideal für die Aufnahme von Bildern und Videosequenzen in großartiger Qualität. Content posten, runterladen oder synchronsieren mit Motorola Media Link. Das Motorola MILESTONE 2 nimmt HD-Videos mit 720p-Signal auf und gibt diese auch in HD wieder. Und das Beste: Da das MILESTONE 2 nach dem DLNA-Standard (Digital Living Network Alliance) arbeitet, können die Videos oder andere Multimedia-Inhalte anschließend mit DLNA-kompatiblen Geräten ausgetauscht werden.
 
Multimedia-Inhalte
Internet - Nachrichten - Multimedia und Online-Communitys
Dank Adobe Flash Player 10.1 kann man außerdem Angebote Tausender Webseiten so sehen, wie sie sein sollen. Ein weiteres Highlight ist der vernetzte Mediaplayer, der neben der Musik die Songtexte sowie zusätzliche Informationen zum Künstler zugänglich macht und Applikationen bietet, um Empfehlungen zu geben und auszutauschen.
 
Mit einem internen Speicher von 8 GB bietet MILESTONE 2 jede Menge Speicherplatz für Multimedia-Inhalte. Dieser lässt sich über die mitgelieferte 8 GB microSD-Karte erweitern. Wem das nicht genügt, kann microSD-Karten von bis zu 32 GB verwenden.
 
Eine Reihe von Google™-Applikationen wie Google Search™, Google Maps™, Google Mail™ und YouTube™ runden die Geräteausstattung ab. Außerdem bietet der Android Market™ Zugang zu Tausenden Apps.
 
Smartes Zubehör
Das MILESTONE 2 wird mit einer 8 GB-microSD-Karte und einem Headset ausgeliefert. Nutzer können die Motorola Media Link Software kostenlos herunterladen, um Musik oder andere Multimedia-Inhalte ganz einfach zwischen dem Smartphone und dem PC auszutauschen
 
 
Zubehör: Multimedia-StationMit weiterem optionalem Zubehör läuft das MILESTONE 2 zuhause, im Auto oder im Büro zur Höchstform auf:
Die optionale Autohalterung ist startklar für die Straße. Sobald das Handy in der Autohalterung steckt, stellt es auf den Automodus um. Mit einer Berührung sind alle Funktionen zugänglich, egal, ob Kontaktauswahl über die Freisprecheinrichtung, Musik, Internetradio, Podcasts, Google Maps™ mit Navigation™ oder vieles mehr. Das Handy lässt sich einfach über das Ladekabel aufladen, das an die Autohalterung angeschlossen werden kann. Mit integriertem GPS und der MOTONAV Schritt-für-Schritt-Navigation gelangt man immer ans Ziel
 

MILESTONE 2 verwandelt sich in der komfortablen Multimedia-Station in eine Schaltzentrale für Filme, Musik, Bilder oder in einen Digitalwecker. Im Desktop-Modus kann das Gerät mit den Wunsch-Apps individualisiert werden. Und das alles, während das Milestone 2 automatisch auflädt. Die Multimedia-Station ist auch mit dem ersten MILESTONE kompatibel.
";2;False;0;;;Motorola Milestone 2 Smartphone;motorola-milestone-2-smartphone;True;True;P-0036;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;499.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40651,6393981481;"75;2095";16;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000424-motorola-milestone-2-smartphone.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000425-motorola-milestone-2-smartphone.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000426-motorola-milestone-2-smartphone.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;BlackBerry Curve 8520;BlackBerry Curve 8520 schwarz;"
BlackBerry Curve 8520
  
 
QWERTZ-Tastatur


Das BlackBerry Curve 8520 Smartphone passt genau in Ihre Hand, in Ihre Tasche - und in Ihr Leben.
Mit dem schlanken und leichten Design liegt es gut in der Hand und bietet hohen Bedienkomfort.
Nachrichten können mit dem BlackBerry Curve 8520 Smartphone mit der vollständigen QWERTZ-Tastatur
einfach und schnell versendet werden. Jeder Buchstabe ist einer eigenen Taste zugewiesen.
Dies erleichtert die Eingabe und fühlt sich ganz natürlich an.
Das helle Display sorgt mit mehr als 65.000 Farben für eine brillante Anzeige, ganz egal, ob Sie sich E-Mails,
Textnachrichten, Videos oder Bilder ansehen.
 
Das BlackBerry Curve 8520 Smartphone ist unmittelbar mit Apple-Computern kompatibel.
Synchronisieren Sie Ihre Kontaktlisten, Kalender, Termine und Notizen mit den Anwendungen,
die Sie am häufigsten nutzen. Wenn Sie die BlackBerry Desktop Software auf Ihrem BlackBerry
Curve 8520 Smartphone verwenden, ist das BlackBerry Smartphone ganz ähnlich zu bedienen
wie Ihr Apple-Computer.
Schlankes vereinfachtes Design
Spezielle Medientasten
Verbindung mit BlackBerry App World
Videokamerafunktionen (2.0 Megapixel-Digitalkamera)
Unterstützung von Apple-Computern
";2;False;0;;;BlackBerry Curve 8520 Smartphone ohne Vertrag;blackberry-curve-8520;True;True;P-0033;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;269.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40651,6285069444;"70;2095";43;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000488-blackberry-curve-8520.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000489-blackberry-curve-8520.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000490-blackberry-curve-8520.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;LG KP500 Cookie;"LG KP500 Cookie schwarz ";"
LG KP500 Cookie
 
LG KP500 Cookie Smartphone
Touchscreenhandy mit iPhone-Feeling für Einsteiger!
Das Full-Touchscreen-Telefon LG KP500 überzeugt durch innovative Technologien und Features, wie sie bislang nur High-End-Telefonen mit kompletter Touchscreen-Bedienung vorbehalten waren.
 
Touchscreen für alle
Die Optimierung der Benutzeroberfläche stand bei der Entwicklung des LG KP500 im Mittelpunkt. Die Onscreen-QWERTZ-Tastatur wird eingeblendet, sobald der Benutzer das LG KP500 quer hält, und das Auto- Rotating-Display zeigt Bilder oder Dokumente immer in der passenden Ausrichtung an, egal wie man das Handy hält.
 
Spielspaß
Darüber hinaus bietet das LG KP500 auch noch Bewegungssensor-Spiele, die für ein aktiveres und spannenderes Spielerlebnis sorgen, indem der Benutzer das Mobiltelefon in die gewünschte Richtung dreht oder neigt.
 
Intuitive Bedienung
Dank seiner intuitiven Benutzeroberfläche kann das LG KP500 mit den klaren Symbolen auf dem 3-Zoll-Display sofort von jedermann verwendet werden. So ist es auch ganz einfach, den Kontakt zu Freunden zu halten.
 
Kurzwahlfunktionen über Icons
Über die innovative Bedienoberfläche kann der Benutzer das Foto von Freunden der entsprechenden Kurzwahl zuordnen und muss dann lediglich zu dem Bild des gewünschten Gesprächspartners blättern und es berühren, um ihn anzurufen.
 
3,0-Megapixel-Digitalkamera
Das großzügige 3""-Display bietet darüber hinaus nicht nur genügend Platz für eine komfortable Bedienung, sondern auch die Möglichkeit Videoclips, eigene Filmchen (max.320 x 240 Pixel, bis zu 24fps) oder Fotos zu betrachten. Diese können mit der 3,0-Megapixel-Digitalkamera (2-faches Digital-Zoom) geschossen und auch per Internet versendet werden.
 
Unterhaltung an Bord
Radio und MP3-Player befinden sich ebenfalls an Bord. Für einfachen Datentransfer besitzt das LG KP500 sowohl einen USB-Anschluss, als auch eine Bluetooth-Anbindung.
 
Reichhaltiger Lieferumfang
Geliefert wird das LG KP500 in schwarzer Farbausführung inklusive Akku, Ladegerät, Stereo-Kabel-Headset, Bedienungsanleitung, USB-Datenkabel, PC-Software und Styluspen.
";2;False;0;;;LG KP500 Cookie;lg-kp500-cookie;True;True;P-0022;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;139.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40651,569375;"72;2095";19;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000247-lg-kp500-cookie.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000248-lg-kp500-cookie.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000249-lg-kp500-cookie.jpg;1;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Sony Ericsson Satio;Sony Ericsson Satio;"
Sony Ericsson Satio
 
Satio - Erlebe Entertainment in nicht für möglich gehaltenen Farbdimensionen.
Das Satio bringt Technik und Ästhetik auf völlig neue Weise zusammen und ist mit einer 12,1 Megapixel Kamera ausgestattet.
Lass Bilder sprechen Mit den einzigartigen Touch Panels tippst du dich direkt in deine beste Musik und deine Lieblingsvideos.
Die leistungsfähige Touchscreen-Kamera liefert dir gestochen scharfe Bilder. Jede Aufnahme ein Meisterstück.
Zum Scharfstellen tippen

Die 12,1 Megapixel Kamera mit Xenon-Blitzlicht und intuitivem manuellen Fokus liefert hochaufgelöste Aufnahmen, die auch auf einem großen Bildschirm beeindrucken.
The Magic Touch
Auf dem Sony Ericsson Satio holst du deine Lieblingsinhalte mit nur einer Berührung auf den Bildschirm.
Ob TV-Serien, Handyvideos, Podcasts oder Musik: Mit dem genialen Fulltouch-Medienmenü dieses beeindruckenden Entertainment-Handys tauchst du direkt ein.
Widescreenwunder
Die 16 Millionen Farben auf dem Sony Ericsson Satio machen Videos und Fotos zum Augenschmaus.
Auf dem gestochen klaren 3,5-Zoll-Bildschirm im 16:9-Format siehst du sie genau so, wie sie gedacht sind.
Symbian OS
Ein offenes Betriebssystem für Mobilgeräte, das Ihnen den Download neuer Anwendungen auf Ihr Handy ermöglicht
TFT-Touchscreen mit 360x640 Pixel und 16,777,216 Farben
unterstützte Netze: GSM/GPRS/EDGE 850/900/1800/1900 UMTS/HSPA 900/2100
12.1 Megapixel mit Autofokus und Bildstabilisator
Betriebssystem: Symbian OS
Lieferumfang:
Sony Ericsson Satio, Verpackung, Akku, Ladegerät, Bedienungsanleitung, Headset, Datenkabel, Handytasche, TV Kabel, Bedienstift
";2;False;0;;;Sony Ericsson Satio;sony-ericsson-satio;True;True;P-0029;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;299.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40651,4580324074;77;35;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000415-sony-ericsson-satio.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000416-sony-ericsson-satio.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000417-sony-ericsson-satio.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Blackberry Bold 9700 QWERTZ;"Blackberry Bold 9700 QWERTZ ";"
Blackberry Bold 9700 QWERTZ
 
Schlank, smart und beeindruckend: Das Flagschiff Blackberry Bold 9700!
 
 
Das Blackberry Bold 9700 ist ein Blackberry Smartphone mit vollständiger QWERTZ-Tastatur in edlem Schwarz!
Es kombiniert praktische Funktionen wie eine 3,2-Megapixel-Autofokuskamera samt Bildstabilisator und Blitz mit
dem Bedienkomfort eines sensitiven Trackpads, das eine mühelose Steuerung aller wichtigen Funktionen per
Fingertip ermöglicht. Im Gegensatz zu seinen Vorgängern wurden behutsame Modifikationen bei der Gestaltung
des User-Interface, der Anordnung von Bedienelementen und technischer Auslegung von Media-Player und
Stereo-Lautsprechern vorgenommen. Ansonsten wartet dieses Smartphone mit bewährten Attributen auf,
darunter geschwungenes und harmonisches Design, sowie ein großes helles Display, das mit seinen brillanten
Farben Webseiten, Fotos, Spiele und Videoclips optimal darstellt.
Smartphone mit hochauflösendem 2,44¿-Farbdisplay mit 480 x 360 Pixeln und mehr als 65.000 Farben
Bedienfreundliches Touchpad und vollständige, beleuchtete QWERTZ-Tastatur
3,2 Megapixel-Digitalkamera mit Autofokus, Bildstabilisierung und 2-fach Digitalzoom
Integrierter A-GPS-Empfänger
Lieferumfang:
Akku, Ladegerät, Stereo-Kabel-Headset, Bedienungsanleitung, USB Datenkabel und PC-Software
";2;False;0;;;"Blackberry Bold 9700 QWERTZ ";blackberry-bold-9700-qwertz;True;True;P-0032;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;499.0000;499.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40651,4502777778;"70;2095";43;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000403-blackberry-bold-9700-qwertz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000404-blackberry-bold-9700-qwertz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000405-blackberry-bold-9700-qwertz.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Samsung Galaxy S Super Clear LCD (i9003) Smartphone;"Samsung Galaxy S Super Clear LCD (i9003) Smartphone (10,1 cm (4 Zoll) Display, Touchscreen, 5 Megapixel Kamera) schwarz ";"
Überirdisch leistungsstark.
Eine Leistungsklasse für sich, das ist das Samsung Galaxy S Super Clear LCD (i9003). Highlight des eleganten Android™-Smartphones ist der extragroße Super Clear LCD-Touchscreen. Hier wird das Betrachten von Videos zum mobilen Kinoerlebnis. Auch das Surfen im Internet geht dank großem Display und Multitouch-Zoom leicht von der Hand. Das Schreiben von E-Mails und SMS gelingt unkompliziert dank Swype®-Texteingabe. Zahlreiche aktuelle und nützliche Apps stehen im Android Market™ zum Download bereit. Die integrierte Google Maps Navigation™ führt ans gewünschte Ziel. Ein erstklassiges Zusammenspiel von Hardware und Funktionen leistet sein Übriges für ein ausgezeichnetes Nutzererlebnis auf höchstem Niveau! Das Samsung Galaxy S Super Clear LCD - überirdisch leistungsstark und galaktisch gut.
 
Unvergessliche Bildqualität
Das Super Clear LC-Display beeindruckt durch seine ausgeprägte Farbtreue und ist deutlich heller und weniger anfällig für reflektierendes Licht als konventionelle LC-Displays. Eine Luftpolsterschicht zwischen Bildschirm und berührungsempfindlicher Schicht des Touchscreens besteht nicht, da die Berührungssensoren direkt auf dem Display angebracht sind. Dies sorgt nicht nur für die sichtbar bessere Farbdarstellung, sondern auch für höhere Schärfe und erlaubt dünnere Displaybauweisen.
 
In bester Kommunikation
Wollen Sie selbstgedrehte Videos oder Bilder mit anderen teilen, gelangen diese auf direktem Wege über das Mobilfunknetz in Social Communities wie zum Beispiel Facebook®, Twitter ™oder MySpace™ – ein Antippen des Touchscreens genügt. Das interaktive Telefonbuch hält Sie übersichtlich darüber auf dem Laufenden, was Ihre Freunde in den Sozialen Netzwerken posten. Ohne, dass Sie deren Profile einzeln aufrufen müssten. Ein Blick genügt.
 
Schnelle Texteingabe
Von den Erfindern der automatischen Textvervollständigung T9 kommt mit Swype® die Revolution der Texteingabe über Touchscreens. Texte werden nicht Buchstabe für Buchstabe eingegeben, sondern einzelne Worte werden ohne abzusetzen mit dem Finger über die virtuelle Tastatur nachgefahren. Texte lassen sich so bis zu 1,5-mal schneller verfassen. Bei mehrdeutigen Eingaben bietet Swype® eine Übersicht in Frage kommender Begriffe. Typische Rechtschreibfehler werden dabei automatisch korrigiert.
 
Kabelloser Datenaustausch
Multimediainhalte bringen Sie spielend leicht auf DLNA™-kompatible Geräte wie Fernseher, PCs und Notebooks. Dank DLNA™-Standard AllShare™ komplett kabellos und ohne lange Einrichtung. Sollte Ihr Fernseher nicht DLNA™-tauglich sein, erweitert das optional erhältliche Multimedia Gateway WMG160 diesen mit der entsprechenden Funktionalität.
 
Mobil arbeiten
ThinkFree® bietet auch unterwegs Zugriff auf lokal oder online gespeicherte Office-Dokumente. Diese stehen zur Ansicht und zur Bearbeitung zur Verfügung.
";2;False;0;;;Samsung Galaxy S Super Clear LCD (i9003) Smartphone;samsung-galaxy-s-super-clear-lcd-i9003-smartphone;True;True;PD-01071;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;469.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40651,4194212963;76;5;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000623-samsung-galaxy-s-super-clear-lcd-i9003-smartphone.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000624-samsung-galaxy-s-super-clear-lcd-i9003-smartphone.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000625-samsung-galaxy-s-super-clear-lcd-i9003-smartphone.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;HTC Desire HD;"HTC Desire HD Smartphone (10,9 cm (4.3 Zoll) Touchscreen, 8MP Kamera, Android OS 2.2, HSPA) Maduro Brown ";"
Innovation, die macht was Sie wollen
Das HTC Desire HD ermöglichtmit der neuesten Technologie, einem 10,9 cm Touchscreen und dem bislang schnellsten Prozessor ein besonderes Interneterlebnis. Es ist mit Android™ 2.2 und der neuesten Version von HTC Sense™ ausgestattet.
 
Ein 10,9 cm WVGA Touchscreen
Der große Touchscreen eigent sich perfektzum Anschauen von Videos, Filmen und Fotos sowie zum Surfen im Internet. Videos können mit einer Auflösung von 720p aufgenommen und in HD-Qualität auf Ihrem TV wiedergegeben werden. Musik wird ganz einfach auf den internen Speicher oder eine SD-Karte übertragen.
 
Das ultimative Interneterlebnis
Die Kombination aus dem 10,9 cm Touchscreenund dem 1 GHz-Prozessor sorgt für das ultimative Interneterlebnis. Sie können mehrere Websites gleichzeitig öffnen und diese parallel nutzen, genau so, wie Sie es von Ihrem PC gewöhnt sind. Die Textanpassung sorgt dafür, dass sich der Text beim Hineinzoomen in eine Website automatisch an das Display anpasst, so dass Sie nicht mehr scrollen müssen. Dank Flash 10.1-Unterstützung werden alle Websites so angezeigt, wie sie aussehen sollen.
 
Mit nur einem Fingertipp...
...Ihre Freunde erreichen
Mit dem Favoriten-Widget können Sie direkt auf Ihrem Homescreen verschiedene Kontaktgruppen mit Freunden oder Kollegen anlegen. Ein Anruf, eine SMS oder eine E-Mail sind dann nur noch einen Fingertipp entfernt.
 
...alle Anwendungen oder Apps bedienen
Sie können jede beliebige Anwendung oder App auf dem 7-teiligen Homescreen platzieren und nach Belieben anordnen, indem Sie sie einfach per Drag & Drop dort hinziehen. So ist alles, was Ihnen wichtig ist, immer nur einen Fingertipp entfernt.
 
Auf Facebook, Twitter und Flickr gleichzeitig zugreifen
Mit Friend Stream sehen Sie alle neuen Facebook-Updates, Tweets und Flickr-Fotos Ihrer Freunde in einer Ansicht, die sich automatisch aktualisiert. Und wenn Sie Ihre eigenen Profile in diesen Sozialen Netzwerken aktualisieren wollen, können Sie das in nur einem Schritt erledigen. 
 
Schöne Momente Festhalten
Mit der 8 Megapixel Kamera erzielen Sie erstaunliche Aufnahmen. Eine hohe Auflösung, großartige Farben und eine Vielzahl an Einstellungsmöglichkeiten bringen ein hohes Maß an Professionalität in Ihre Aufnahmen. Im dunkler Umgebung helfen Ihnen 2 LED-Blitze, immer alles im Bild zu haben. Und auch Videos erscheinen nun in HD-Auflösung. Erfassen Sie Ihre nächste Geburtstagsparty, die Firmenfeier oder Ihre Freunde in 720p Qualität.
Sehen Sie alles auf einem großen Display
Vorbei sind die Zeiten, in denen Sie Texte auf winzigen Displays entziffern mussten und die entscheidenden Informationen übersehen haben. Auf dem 10,9 cm großen Display des HTC Desire HD genießen Sie ein wahrhaft großartiges Interneterlebnis. Mit Features wie der gestochen scharfen Textdarstellung und der brillanten Wiedergabe von Fotos und Videos ist das HTC Desire HD wie dafür geschaffen, Ihre Lieblingswebsites, YouTube-Clips und Facebook-Fotos optimal wiederzugeben.
 
Ein Handy, das Sie nicht verlieren können
Mit HTC Sense™ können Sie Ihr Handy aus derFerne über ein sicheres Web-Portal steuern. Sie können es anweisen zu klingeln, selbst wenn es stumm geschaltet ist, um es wiederzufinden, oder Sie sperren es und löschen alle Inhalte, falls es gestohlen wurde. Sie können eine Nachricht an Ihr Handy senden, in der Sie den Finder um die Rückgabe bitten. Kontakte, SMS und MMS können gesichert werden, sodass sie einfach wieder hergestellt werden können.
";2;False;0;;;HTC Desire HD Smartphone;htc-desire-hd;True;True;;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;3,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;299.0000;299.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40651,414375;"73;2095";36;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000621-htc-desire-hd.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000622-htc-desire-hd.jpg;;1;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;HTC HD7;"HTC HD7 Smartphone (10,9 cm (4,3 Zoll) Touchscreen, Windows Phone 7, 5MP Kamera, GPS, Dolby Mobile, 8 GB interner Speicher, ohne Branding) schwarz ";"
Mobiles Entertainment in High Definition
Das HTC HD7 ist das ultimative Handy für die Wiedergabe von Filmen. Denn durch das Widescreen-Display, den hochwertigen Klang und den großen Speicher erleben Sie auch unterwegs perfektes Kino.
 
Großes Display und toller Klang
Genießen Sie Ihre Filme auf dem riesigen 10,9 cm Widescreen-Display. Dabei müssen Sie Ihr Handy nicht die ganze Zeit in der Hand halten – klappen Sie einfach den Ständer aus und lehnen Sie sich bequem zurück. Durch die Dolby Mobile-Technologie erleben Sie auch unterwegs einen bislang unerreichten Klang in Kinoqualität. Mit Zune® haben Sie ein perfektes Mediencenter, denn damit können Sie auch unterwegs Inhalte herunterladen und diese mit Ihrem PC synchronisieren. 8-16 GB integrierter Speicher sorgen für genug Platz, um all Ihre Filme, Musik und Spiele überallhin mitzunehmen.
 
Neue Features mit Windows Phone 7
Freuen Sie sich darauf, mit weniger Bedienschritten mehr zu erledigen. Nutzen Sie den Windows® Phone Marketplace für den schnellen, bequemen Einkauf und besuchen Sie den HTC Hub für weitere Windows® Apps, die für HTC-Nutzer kostenlos sind. Langeweile ist dank Xbox Live® Gaming auf Ihrem Handy kein Thema mehr.
 
Der Mensch an erster Stelle
Auf dem HTC HD7 finden Sie die gesamte Kommunikation mit Ihren Kontakten an einem Ort. So haben Sie direkt Zugriff auf Facebook®- und Windows® Live-Updates und Fotos, SMS und MMS, E-Mails und Anrufe. Die Personen, die Sie zuletzt kontaktiert haben, werden Ihnen auch zuerst angezeigt oder Sie gehen alternativ Ihre ganze Kontaktliste durch.
 
Momente festhalten und teilen
Mit der integrierten 5 Megapixel Kamera halten Sie jeden Augenblick fest. Ob Firmenveranstaltungen, Geburtstagsfeiern, Trips durch die Natur - Ihr HTC HD7 lässt Sie nie im Stich. Der eingebaute Blitz hilft Ihnen, selbst an dunklen Orten ein scharfes Bild zu erhalten. Direkt nach der Aufnahme, können Sie dieses auf einer der unzähligen Social Network Seiten veröffentlichen und so mit Ihren Freunden und Bekannten teilen.Mit der Videofunktion zeichnen Sie verblüffende HD-Videos mit 720p auf
";2;False;0;;;HTC HD7 Smartphone;htc-hd7;True;True;PD-01069;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;3,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;299.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40651,4104166667;73;36;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000619-htc-hd7.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000620-htc-hd7.jpg;;1;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Blackberry Bold 9000;Blackberry Bold 9000 black;"
Blackberry Bold 9000  
 
 
WLAN, GPS, QWERTZ-Tastatur, Kamera mit 2 MP, MP3-Player

 
Das BlackBerry Bold Smartphone ist Innovation pur
Mobile Komplettlösung mit hinterleuchteter QWERTZ (Tastatur), beweglichem Trackwheel und 480 x 320 Pixel Display
 
Verfügbare Funktionen:
Mobile E-Mail, Organizer, Mobiles Internet, Telefon, Kamera, Videoaufnahme, Media Player, Zugriff auf Unternehmensdaten, SMS, MMS, GPS & Blackberry Maps
Erweiterbarer Speicherplatz - unterstützt microSD-Karten, 1 GB integrierter + 128 MB Flash-Speicher
Unterstützt Tri-Band-HSDPA, Quad-Band-GSM/EDGE 3G und WLAN 4 und kann als Hochgeschwindigkeits-Modem mit 3,6 MB/s eingesetzt werden
";2;False;0;;;Blackberry Bold 9000;blackberry-bold-9000;True;True;P-0031;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;459.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40651,1651736111;"70;2095";43;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000370-blackberry-bold-9000.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000371-blackberry-bold-9000.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000372-blackberry-bold-9000.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Blackberry Curve 8900;Blackberry Curve 8900;"
Blackberry Curve 8900 
 
 
WLAN, GPS, QWERTZ-Tastatur, BlackBerry Maps, Organizer, Kamera mit 3,2 MP, MP3-Player
 
 
Deutsche Tastatur im QWERTZ-Layout mit beweglichem Trackball, ESC- und Menütaste zur intuitiven Menüsteuerung, hochauflösendes 2,44 Zoll-Farbdisplay mit 480x360 Pixel
 
Verfügbare Funktionen:
WLAN-kompatibel IEEE 802.11b/g, Integrierter GPS-Empfänger, Media Player für Audio und Video, Videoaufzeichnung, BlackBerry Maps, Mobile E-Mail, Organizer, Browser, Mobiltelefon, Zugriff auf
Unternehmens-EDV, SMS/MMS
 
3,2 Megapixel-Kamera mit Autofokus, automatischem Blitz und Bildstabilisierung, Videofunktion
Netzkompatibilität: GSM 900/1800/GPRS (Europa, Asien, Australien, Südamerika (teilw.)), CDMA 850/1900/GPRS (Nordamerika), EDGE
";2;False;0;;;Blackberry Curve 8900;blackberry-curve-8900;True;True;P-0035;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;359.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40651,1558101852;70;43;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000365-blackberry-curve-8900.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000366-blackberry-curve-8900.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000367-blackberry-curve-8900.jpg;1;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;HTC Touch 2;HTC Touch 2;"
HTC Touch 2 
 
Das HTC Touch2 macht es Ihnen leicht
 
  
Bleiben Sie in Kontakt mit Ihren Freunden, finden Sie heraus, was es bei Facebook Neues gibt, rufen Sie Ihre Mails ab oder surfen Sie im Web.
All diese Möglichkeiten stehen Ihnen auf Fingerdruck zur Verfügung – mit einem kompakten Telefon, das perfekt in der Hand liegt.
Sie möchten noch mehr mit dem Touch2 erleben? Dann laden Sie doch einfach Spiele und Anwendungen aus dem Windows Marketplace auf Ihr Handy, um es noch besser an Ihre Wünsche anzupassen.
Und damit Ihre Daten jederzeit sicher sind, können Sie direkt auf dem Microsoft MyPhone-Server ein Backup anlegen – ohne einen PC dafür zu benötigen.
Der HTC Touch2 bietet zahlreiche Verbesserungen bezüglich des TouchFLO, des User Interface (Wetterbericht, Shortcuts zu den beliebtesten Anwendungen...) und die Einführung von Google Maps für Mobiltelefone, YouTube und vieles mehr.
Touch2 - Technische Details :
Displaytaktiles 2.8"" TFT-LCD Display mit QVGA Auflösung Windows Mobile® 6.5
Professionaltaktile Front Panel Buttons für einfache Bedienbarkeit NetworkSchnelles Surfen und hohe Download-Geschwindigkeiten dank HSDPA
GPSintegrierte GPS Antenne
Fotoapparat3.2 Megapixel mit der Möglichkeit, Videos aufzunehmen
AnschlüsseWi-Fi (IEEE 802.11 b/g), Bluetooth 2.0, 3.5 mm Audioanschluss
Betriebssystem: HTC TouchFLO mit Windows Mobile 6.5 Professional
Verbindungsoptionen: GSM/Edge (850/900/1800/1900 MHz), WCDMA/HSDPA (900/2100 MHz), HSDPA (7,2 Mbps)
Gesprächszeiten: WCDMA bis zu 370 Minuten, GSM bis zu 440 Minuten
Standby-Zeiten: WCDMA bis zu 500 Stunden, GSM bis zu 370 Stunden
";2;False;0;;;HTC Touch 2;htc-touch-2;True;True;P-0016;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;299.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40650,9831712963;73;36;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000577-htc-touch-2.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"HTC HD2 ";"HTC HD2 in edlem schwarzen Design ";"
HTC HD2 in edlem schwarzen Design
  
Windows Mobile 6.5; 4,3 Zoll WVGA Touchscreen Display, 5 Megapixel-Kamera mit Auto-Fokus und LED Blitzlicht
 
Mit dem HTC HD2 präsentiert die HTC Corporation, weltweiter Marktführer bei Telefonen auf Basis von Windows Mobile und Android, das neue Flaggschiff seiner Windows Phone-Familie.
 
Der HTC HD2 ist das weltweit erste Windows Phone mit HTC Sense, einem mobilen Erlebnis, das den Anwender und seine natürlichen Handlungsstränge in den Mittelpunkt stellt.
Mächtige Leistungsreserven verspricht der mit 1 GHz getaktete Snapdragon-Prozessor von Qualcomm, der den HTC HD2 zur ultimativen Surf-, Multimedia- und Gaming-Maschine macht.
Erstes Windows Phone mit HTC Sense
HTC Sense basiert auf drei fundamentalen Prinzipien, die durch Zuhören und Beobachten, wie Menschen leben und kommunizieren, ermittelt wurden: Make it Mine, Stay Close und Discover the Unexpected.
Make it Mine
Der HD2 lässt sich maßgeschneidert an individuelle Anforderungen anpassen. Und dabei spielt das brillante Display seine gesamte Größe aus.
 
Animierte Hintergründe oder Wetterapplikationen (bei Regen fallen Regentropfen, bei bewölktem Himmel ziehen Wolkenschwaden über den Bildschirm etc.) vermitteln ein einzigartiges Erlebnis,
ohne dabei andere wichtige Anwendungen oder Inhalte zu stören.
Eine Vielzahl an Unterhaltungs- und Zusatzapplikationen aus dem Windows Marketplace for Mobile lädt zudem ein, den HD2 komplett an die eigenen Vorlieben anzupassen.
Stay Close
Egal über welche Art von Kommunikationskanal (Sprache, SMS, Email, Facebook etc.) die Verbindung mit Freunden, Verwandten oder Geschäftspartnern aufrecht gehalten werden soll,
der Personen-bezogene Kommunikationsansatz von HTC stellt zu jeder Kontaktperson die gesamte Konversationshistorie auf einen Fingerstreich zur Verfügung.

Discover the Unexpected
Auf Basis des mobilen Erlebnisses HTC Sense hält der HTC HD2 eine Vielzahl an Erweiterungen bereit, die den Umgang mit dem Smartphone-Giganten spürbar vereinfachen.
 
Der HD2 verfügt über diverse Sensoren, unter anderem einen Näherungssensor, der Fehleingaben während eines Telefonats verhindert.

Lieferumfang:
HTC Touch HD2, Akku, Ladekabel, USB-Kabel, kabelgebundenes Headset
";2;False;0;;;HTC HD2 Smartphone;htc-hd2;True;True;P-0011;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;3,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;599.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40650,9376967593;"73;2095";36;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000386-htc-hd2.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000387-htc-hd2.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000388-htc-hd2.jpg;1;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Sony Ericsson XPERIA X10 Mini Pro Smartphone;Sony Ericsson XPERIA X10 Mini Pro Smartphone (6,6 cm (2,6 Zoll) Display, QWERTZ-Tastatur, Android, WLAN, GPS, 5 Megapixel Kamera;"
Leistungsmerkmale des Sony Ericsson X10 Mini Pro Smartphone
Cleveres Zubehör
Rufen Sie Ihre Freunde an und lassen Sie Sich anrufen. Hören Sie Musik, halten Sie die Musik an und überspringen Sie einen Titel. Ganz ohne Ihr Handy. Sind Sie auf der Suche nach portablen Stereo-Lautsprechern? Die Sony Ericsson MS450 Lautsprecher (Optional) oder einem Hi-Fi-Headset mit Fernbedienung (z.B. Sony Ericsson MH810 - Optional)? Lassen Sie Ihr Handy in der Tasche und verwenden Sie Ihr Zubehör als Fernbedienung.
 
Timescape™ - Freunde treffen
Sony Ericsson Timescape™ ermöglicht die Anzeige der gesamten Kommunikation an einem Ort. Facebook™, Twitter™, SMS, Anrufe in Abwesenheit - alles in einer Anwendung zusammgefasst. Jede Menge geöffnete Anwendungen, um zu sehen, was gerade los ist? Die Zeiten sind endlich vorbei.
 
Mit der Kraft von QWERTZ
Sie tippen lieber auf einer Tastatur? Mit der kompletten QWERTZ-Tastatur können Sie Nachrichten noch einfacher schreiben.
 
Alles von überall
Die gesamte Kommunikation mit Ihren Freunden über das Telefonbuch. Alle Informationen zu Interpreten über den Music-Player. Einfach die Infinity-Taste berühren und schon werden alle Informationen angezeigt. Sofort.
 
Individuelle Freiheit
Ihre unverzichtbare Navigationsanwendung? Ihre Musik? Eine News-Site? Sie entscheiden, was wichtig für Sie ist. Wählen Sie die Symbole für die vier Ecken auf dem Startbildschirm selbst aus. Sie können die Anordnung jederzeit wieder ändern. In der Mitte des Bildschirms können Sie ein Widget einfügen. Gestalten Sie Ihren Bildschirm frei nach Ihren individuellen Bedürfnissen.
 
Android - Google - Apps
Das Xperia™ X10 Mini basiert auf der Android™-Plattform. Sie haben die Möglichkeit alle Google™-Anwendungen im vollen Umfang genießen zu können – Google Search™, Google Voice Search™, Google Talk™, Gmail™, YouTube™, Google™ Maps und dem Android Market™.
 
Selbst aussuchen - Android Market™
In Ausgehstimmung? In Aufbruchlaune? Oder im Ausruhmodus? Downloaden Sie jede beliebige Anwendung vom Android Market™ und passen Sie Ihr Xperia™ X10 Mini nach Ihren individuellen Vorlieben an.
 
HSPA – rasante Geschwindigkeit
Turbo-UMTS ermöglicht Ihnen breitbandähnliche Geschwindigkeiten auf dem Handy. Laden Sie große Dateien und E-Mail-Anhänge in wenigen Augenblicken herunter. Holen Sie sich Websites und Newsfeeds in Sekunden auf den Bildschirm.
 
Finden Sie Ihr Ziel - mit aGPS
Nie wieder verlaufen. Ihr Telefon verfügt über integriertes aGPS. Ortsgebundene Dienste helfen Ihnen, den Weg an Ihr Ziel zu finden. Oder fügen Sie Ihren Bildern mit der Geo-Tagging-Funktion Ortsangaben hinzu.
 
UKW-Radio
Musik liegt in der Luft - einfach einstellen und genießen. Ihr Handy verfügt über ein integriertes UKW-Radio.
 
Wi-Fi-Verbindung
Schnell und einfach in Verbindung bleiben. Unterwegs. In Cafés. Am Flughafen. Ihr Xperia™ X10 Mini unterstützt Wi-Fi.
";2;False;0;;;Sony Ericsson XPERIA X10 Mini Pro Smartphone;sony-ericsson-xperia-x10-mini-pro-smartphone;True;True;P-0027;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;159.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40650,9259606482;77;35;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000476-sony-ericsson-xperia-x10-mini-pro-smartphone.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000477-sony-ericsson-xperia-x10-mini-pro-smartphone.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000478-sony-ericsson-xperia-x10-mini-pro-smartphone.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Apple iPod touch 4G 64 GB ";"Der neue iPod touch. Jetzt mit FaceTime, Retina Display, HD-Video und Game Center. ";"
Der neue iPod touch. Jetzt mit FaceTime, Retina Display, HD-Video und Game Center.
 
Spaß, hoch entwickelt. Der neue iPod touch.
Tonnen von innovativen Funktionen gibt es jetzt auch auf dem iPod touch. Einfach damit er noch mehr Spaß macht. Teilen Sie schöne Momente mit Freunden via FaceTime. Nehmen Sie Videos in HD auf. Oder erleben Sie Spiele auf dem höchstauflösenden iPod Display, das es je gab. Der iPod touch hat so viel Technologie, dass Sie glatt vergessen, dass es ein iPod ist.
 
Sieht unglaublich aus. Ist aber wahr.

Mit seinem neuen Design ist der iPod touch der dünnste, leichteste und fantastischste iPod touch, den es je gab. Um das zu spüren, müssen Sie ihn nur in die Hand nehmen. Er ist gerade mal 7,2 mm dünn. Mit seiner Vorderseite aus Hightech-Glas und der Rückseite aus Edelstahl fühlt er sich einfach fantastisch an. Wenn Sie ihn einschalten, sind Sie sofort vom brillanten Retina Display fasziniert. Der iPod touch kombiniert großartiges Design und revolutionäre Technologie - von außen wie von innen.
 
Retina Display. Die Zukunft sieht gut aus.
Es gibt viele Gründe, den iPod touch immer wieder anzusehen. Beispielsweise das LCD-Display mit 960 x 640 Pixeln und Hintergrundbeleuchtung. Es hat eine Pixeldichte von 326 ppi und ist damit das höchstauflösende iPod Display, das es je gab. Die Apple Ingenieure haben dafür superkleine, kaum 78 Mikrometer breite Pixel entwickelt, die das menschliche Auge nicht mehr als einzelne Pixel wahrnehmen kann. Und obwohl Sie sie nicht sehen können, werden Sie den Unterschied bemerken. Der Text ist gestochen scharf und alles sieht leuchtend und lebendig aus.
 
Apple A4 Prozessor. Mehr Power für Sie.
Hinter - oder besser gesagt unter - dem ganzen Spaß, den Sie mit dem iPod touch haben, steckt der Apple A4 Chip. Die Apple Ingenieure haben den A4 Chip als leistungsstarken und energieeffizienten Mobilprozessor entworfen. Damit bewältigt der iPod touch komplexe Aufgaben wie Multitasking, Videoschnitt und FaceTime Anrufe. All das bei noch mehr Batterielaufzeit. Und mehr Spaß.
 
Gyrosensor + Beschleunigungssensor. Wirklich bewegend.
Der iPod touch hat jetzt ein paar neue Tricks drauf. Er hat einen integrierten 3-Achsen-Gyrosensor, der zusammen mit dem Beschleunigungssensor dafür sorgt, dass der iPod touch Aktionen wie Beschleunigung, 3D Bewegung und Drehrate erkennt. Im Klartext: Mehr Bewegungen, mehr Gesten und größere Präzision für noch mehr Spielspaß.
 
Zwei Kameras. Doppelt so viel Spaß.
Für Videoaufnahmen hat der iPod touch zwei integrierte Kameras. Mit der Rückkamera nimmt er fantastische HD 720p Videos auf. Und der hoch entwickelte rückwärtig belichtete Sensor sorgt selbst bei schwacher Beleuchtung für tolle Aufnahmen. Das integrierte Mikrofon nimmt dabei gleichzeitig Gespräche, Musik oder alles andere auf. Die Frontkamera des iPod touch ist perfekt für FaceTime Anrufe1 und um sich selbst aufzunehmen. Schon erstaunlich, wie viel Spaß in etwas so Kleines passt.
Multi-Touch. Alles unter Kontrolle Ihrer.
Wie macht der iPod touch eigentlich genau das, was Sie wollen, wenn Sie mit Ihren Fingern über das Display streichen? Genau genommen ist es eine Kettenreaktion. Das Multi-Touch Display hat einen Schutzfilm über der kapazitiven Sensorik, die Berührungen anhand elektrischer Felder erkennt. Diese Informationen werden an das Retina Display darunter übermittelt. So könen Sie alles mit den Fingern steuern, mit Cover Flow in Ihren Alben blättern, Fotos sehen und vergrößern, in eine Website zoomen und Spiele steuern.
 
FaceTime auf dem iPod touch. Sagen Sie nicht einfach Hallo. Sagen Sie es mit einem Lächeln.
Ein Lächeln sagt mehr als tausend SMS.
Bringen Sie LOL auf die nächste Stufe und sehen Sie Ihre Freunde wirklich lachen. Oder lassen Sie XOXO lebendig werden und schicken Sie einen Kuss um die halbe Welt. FaceTime auf dem iPod touch macht's möglich. FaceTime funktioniert sofort nach dem Auspacken - Sie geben einfach Ihre Apple ID und E-Mail Adresse ein. Oder erstellen einen neuen E-Mail Account extra für FaceTime. FaceTime ist supereinfach. Stellen Sie sich vor, Sie wollen über Wi-Fi mit Ihrer besten Freundin videotelefonieren. Dann tippen Sie auf die FaceTime App, finden sie dort und starten den Anruf. Auf ihrem iPod touch oder iPhone 4 erscheint dann eine Einladung, die sie annehmen kann. Sobald sie annimmt, wird FaceTime gestartet. Das alles funktioniert ganz nahtlos und sowohl im Hoch- als auch im Querformat. Sie werden im wahrsten Sinne des Wortes sehen, wie viel Spaß Sie haben können.
 
Videotelefonieren Sie mit Freunden per FaceTime oder spielen Sie gegen Freunde oder Fremde mit Game Center.
 
Zwei Kameras für Spaß von jeder Seite.
Der iPod touch hat zwei Kameras - eine vorne über dem Display und eine auf der Rückseite. Die Frontkamera ist für FaceTime optimiert. Sie hat genau das richtige Sichtfeld und die richtige Brennweite, um auf die Entfernung einer Armlänge das Gesicht zu fokussieren. So zeigt sie Sie immer im besten Licht. Was besonders praktisch ist, wenn Sie mit jemandem sprechen, der mehr als nur ein Freund ist.
Die Rückkamera. Teilen Sie Ihre Ansicht.
Wenn Ihre Mitbewohnerin es doch nicht mehr zum Konzert schafft, lassen Sie sie mit FaceTime doch wenigstens die Zugabe sehen. Wenn die Band auf die Bühne kommt und ihren Lieblingshit spielt, tippen Sie einfach auf die Taste. Und noch bevor der Sänger die erste Zeile singt, wechselt der iPod touch zur Rückkamera und überträgt einen mit Sicherheit legendären Auftritt. Tippen Sie noch einmal und der iPod touch wechselt zurück auf die Frontkamera und zu Ihnen. Einfach und schnell - macht einfach Spaß!
 
HD Videoaufnahme auf dem iPod touch. Nehmen Sie jeden Spaß mit. Und auf.
 
Integrierter Schnittplatz.
Sie müssen mit dem Bearbeiten Ihrer Videos nicht warten, bis Sie wieder am Computer sitzen. Einfache Schnittfunktionen sind direkt im iPod touch integriert, sodass Sie gleich damit loslegen können. Ziehen Sie einfach, um Start- und Endpunkt des Films festzulegen. Behalten Sie nur die Teile des Videos, die Ihnen besonders gefallen, und machen Sie daraus einen Film, den Sie und Ihre Freunde immer und immer wieder anschauen wollen.
 
Mit iMovie auf dem iPod touch erstellen Sie Minikinofilmhits mit ein paar Fingertipps.
Stellen Sie sich vor, Sie sind unterwegs und wollen eine Videopostkarte erstellen, mit allem, was Sie erlebt und gesehen haben. Machen Sie das einfach mit der iMovie App - Sie bekommen sie im App Store. Mit iMovie für den iPod touch können Sie Videoclips zusammenfügen und bearbeiten, ihnen mit dynamischen Themen und Übergängen noch eine Extraportion Wow geben, Musik und Fotos hinzufügen und den fertigen Film mit allen teilen.
 
Drehen Sie einen Film. Mit Ihnen in der Hauptrolle.
Wenn Sie das nächste Mal eine aufregende Wanderung gemacht haben, erzählen Sie Ihren Freunden nicht nur davon - zeigen Sie es ihnen. Neben der HD Kamera auf der Rückseite besitzt der iPod touch eine Frontkamera mit VGA-Qualität über dem Display. So sehen Sie sich selbst, während Sie Videos aufnehmen. Das ist perfekt, um sich selbst zu filmen, denn Sie brauchen nicht mehr zu hoffen, dass Sie im Bild sind, sondern sehen es gleich. Also machen Sie sich bereit für die Aufnahme.
 
Teilen Sie mit Freunden den Rest Ihres Lebens.
Haben Sie auch schon mal eine Mail geschrieben und dabei etwas Unbeschreibliches gesehen? Dann nehmen Sie die Kamera und nehmen Sie es auf. Anschließend können Sie Ihren HD Film direkt auf YouTube laden. Oder wählen Sie ein Video aus den Aufnahmen und verschicken es mit einer Mail. Sie können es auch mit einem Fingertipp auf Ihre Facebook Seite oder in Ihren Blog posten. Und alle mit dem iPod touch aufgenommenen Videos ganz leicht mit Ihrem Mac oder PC synchronisieren.
So haben alle ein gutes Bild von Ihnen.

Eine unglaubliche Aussicht. Ein toller Kuchen. Ihr Hund, wie er soooooo süß schaut. Wenn Sie einen Schnappschuss für Facebook machen wollen, können Sie eine der beiden Kameras des iPod touch verwenden. Tippen Sie einfach auf das Display, um die Belichtung anzupassen. Dann posten Sie das Bild auf Facebook und warten auf die Kommentare.
 
Game Center. Spielen Sie gegen Ihre besten Feinde
Game Center. Mögen die Spiele beginnen.
Mit der neuen Game Center App auf dem iPod touch können Sie Ihr Spiele-Netzwerk erweitern. Exponentiell. Zum Spielen brauchen Sie nur einen iPod touch oder ein iPhone mit iOS 4.1. Bei iOS 4.1 wird eine Game Center App auf dem Homescreen angezeigt. Tippen Sie einfach darauf, meldes sich mit Ihrer Apple ID an und schon kann´s losgehen. Sie können einen Spielernamen erstellen, der für Ihre Freunde und die Spieler-Community sichtbar ist. Fügen Sie mehrere E-Mail Adressen zur Game Center App hinzu, damit Freunde Sie einfacher finden können. Sie können die Spiele über die Links im Game Center laden und auch direkt aus der Game Center App starten. Und das Beste: Sobald Sie sich bei Game Center anmelden, bleiben Sie verbunden. Bis Sie dich wieder abmelden.
 
Beste Freunde. Bald beste Gegner.
Treten Sie gegen Ihre Freunde in einem Rennen an. Oder einem Match. Oder in einem Kampf. Wenn Sie bei der Game Center App angemeldet sind, können Sie jemanden mit einer Freundschaftsanfrage einladen und dafür den Spielernamen oder die E-Mail Adresse der Person verwenden. Ihre Freunde erscheinen in einer separaten Freundeliste in der Game Center App. Tippen Sie auf die Namen von Freunden und Sie sehen, welche Spiele sie gespielt haben. Sie können auch neue Freundschaftsanfragen ansehen und eigene hinzufügen.
Leaderbords und Erfolge. Damit jeder sieht, wo Sie stehen.
Sehen Sie sich auf den Ranglisten für jedes Spiel Ihre Platzierung unter Ihren Freunden und anderen Spielern an. Sie können auch Ihre Erfolge mit denen Ihrer Freunde vergleichen. Sehen Sie sich die Leaderboards und Erfolge in der Game Center App und jedem einzelnen Spiel an. Und dann lassen Sie es krachen.
 
Trefen Sie Ihre Gegner. Und treffen Sie sie hart.
Sie möchten eine Runde mit mehreren Freunden spielen? Mit Auto-Match werden Ihnen zuerst Ihre Freunde als Gegner vorgeschlagen, wenn diese auch nach einem Auto-Match suchen. Wenn nicht, wird Ihnen ein Freund in spe irgendwo auf dem Globus als Gegner vorgeschlagen. Oder laden Sie Ihre Freunde ein und lassen Sie Auto-Match alle für ein Spiel benötigten Spieler finden.
Musik. Lassen Sie Ihre Finger tanzen.
Cover Flow. Musik sieht so gut aus.
Auf dem iPod touch gibt's Musik nicht nur auf die Ohren. Mit Cover Flow ist sie auch was für Augen und Finger. Drehen Sie den iPod touch auf die Seite und blättern Sie durch Ihre Albumcover. Tippen Sie auf ein Cover, um es umzudrehen und die Songliste zu sehen. Noch ein Tipp und die Musik läuft.
 
Genius Wiedergabelisten. In jedem guten Song steckt eine noch bessere Wiedergabeliste.
Angenommen Sie hören einen Song auf einem iPod touch, der Ihnen gut gefällt, und möchten weitere Titel hören, die gut dazu passen. Genius findet weitere Songs auf Ihrem iPod touch und erstellt eine Genius Wiedergabeliste. Hören Sie sich die Liste sofort an, speichern Sie sie für später oder versuchen's noch einmal und sehen, was dabei herauskommt. Verlassen Sie sich auf Genius, wenn Sie einen Mix wollen, auf den Sie selbst nie gekommen wären. 
 
Genius Mixe. Nehmen Sie den DJ mit nach Hause.
Genius ist Ihr persönlicher DJ. Synchronisieren Sie Ihren iPod touch mit iTunes und Genius durchsucht Ihre Mediathek automatisch nach Songs, die gut zusammenpassen. Dann erstellt Genius mehrere Mixe. Diese Mixe sind wie Radiosender, auf denen nur Ihre Lieblingshits laufen. So finden Sie Songs wieder, die Sie lange nicht mehr gehört haben oder von denen Sie gar nicht mehr wussten, dass Sie sie haben.
 
Lassen Sie Ihre Finger tanzen. 
 
Shake to shuffle. So ein Zufall.
Die Dinge mal aufrütteln. Musikalisch natürlich. Wenn Sie das nächste Mal Musik hören, aktivieren Sie einfach die Schüttelfunktion. Wenn Sie den iPod touch dann kurz schütteln, springt er nach dem Zufallsprinzip zu einem anderen Song in Ihrer Sammlung. So entdecken Sie Ihre Musik immer wieder neu.
 
iTunes. Das ist Entertainment.
Packen Sie Songs und Musikvideos aus Ihrer iTunes Mediathek auf dem Computer auf den iPod touch. Oder kaufen und laden Sie neue Songs auf den iPod touch, wenn Sie sich über Wi-Fi mit iTunes verbinden. Wenn Sie dann den iPod touch das nächste Mal mit dem Computer verbinden, werden alle Songs, die Sie auf dem iPod touch gekauft haben, auf den Mac oder PC übertragen. Und mit iTunes Ping können Sie jetzt sehen, welche Musik Ihre Freunde hören, kaufen und empfehlen. Oder informieren Sie sich dort über Ihre Lieblingskünstler und was sie so hören.
 
Bluetooth. Entfesseln Sie Ihre Musik.
Die Unterstützung für das drahtlose Bluetooth ist im iPod touch schon drin. Das heißt, Sie können drahtlose Stereokopfhörer verwenden. Lassen Sie den iPod in Ihrer Tasche stecken oder auf dem Schreibtisch aufladen, während Sie weiter Musik hören.
 
Filme und Fernsehsendungen. So haben Sie überall eine Sehenswürdigkeit.
Ganz großes Kino. Auf einem kleinen Display.
Mit dem iPod touch ist jeden Tag und überall Kinotag. Nehmen Sie Videos für viele Stunden Unterhaltung mit und sehen Sie sie auf dem fantastischen 3,5 Zoll Retina Display an. Kaufen Sie im iTunes Store und wählen Sie aus tausenden Filmen, Fernsehsendungen und Video-Podcasts für Ihren iPod touch. Da ist für jeden etwas dabei - von Hollywood Blockbustern bis zu Independent Filmen. Ein paar Fingertipps und Sie haben Filme geladen und können sie ansehen. Sie mögen lieber Fernsehsendungen? Die gibt's auch. Sie können einzelne Folgen oder gleich eine ganze Staffel kaufen. Mit dem iPod touch haben Sie Ihre Videos immer dabei.
Sie haben alles unter Kontrolle.
Wenn Sie ein Video schauen, tippen Sie einfach auf das Display und schon haben Sie die Steuerung. Damit können Sie die Wiedergabe starten oder unterbrechen, zu einzelnen Kapiteln springen und die Lautstärke anpassen. Oder verwenden Sie die Lautstärketasten links am iPod touch. Wenn Sie zwischen Widescreen- und Vollbildanzeige wechseln wollen, reicht ein Doppeltipp auf das Display. Das ist wie die Fernbedienung des Fernsehers. Nur, dass Sie nicht darum kämpfen müssen.
 
iTunes. Für beste Unterhaltung.
Sie brauchen für den nächsten Flug oder die nächste Fahrt etwas Unterhaltung? Mit iTunes auf dem iPod touch und einer Wi-Fi Verbindung können Sie sofort Filme und Fernsehsendungen kaufen. Oder Sie kaufen sie auf Ihrem Mac oder PC und synchronisieren sie mit dem iPod touch. Nur das Popcorn ist nicht dabei.
 
 
Besuchen Sie Ihre Lieblingswebsites. Alles, was Sie dazu brauchen, ist ein iPod touch und Wi-Fi. 
 
Laden Sie die iBooks App kostenlos und Sie haben nicht nur einen großartigen E-Book-Reader, sondern auch einen tollen Ort, um Bücher zu kaufen. 
 
Und vieles mehr...
 
App Store
Laden Sie Apps direkt auf den iPod touch
 
iTunes
Erstellen Sie einen iTunes Store Account und kaufen Sie jederzeit via Wi-Fi ein.
 
iBooks
Laden Sie die iBooks App kostenlos und Sie haben nicht nur einen großartigen E-Book-Reader, sondern auch einen tollen Ort, um Bücher zu kaufen.
 
iMovie
Bearbeiten Sie Videos, fügen Sie Themen und Musik hinzu und teilen Sie Ihre Filme mit Anderen
 
Mail
Senden Sie Mails und sehen Sie sich Anhänge von Ihrem Google Mail, MobileMe oder einem anderen E-Mail Account an.
 
Safari Webbrowser
Besuchen Sie Ihre Lieblingswebsites. Alles, was Sie dazu brauchen, ist ein iPod touch und Wi-Fi.
 
Fotos
Nehmen Sie Ihre Fotos mit. Teilen Sie sie per E-Mail. Wählen Sie Ihr Lieblingsfoto als Hintergrundbild.
 
Homescreen
Ordnen Sie in iTunes Ihre Apps auf mehreren Homescreens an.
 
 
Sprachsteuerung
Steuern Sie die Musik auf dem iPod touch mit Sprachbefehlen
 
Karten
Finden Sie Restaurants, Konzerte und mehr und lassen Sie sich mit Karten zeigen, wie Sie hinkommen.
 
YouTube
Sehen Sie sich die neuesten Videohits und Ihre Lieblingsvideos an.
 
Nike + iPod
Erreichen Sie Ihre Trainingsziele mit integrierter Unterstützung für Nike + iPod
 
Sprachmemos
Nehmen Sie Notizen, Gedanken oder alles andere auf.
 
Bedienungshilfen
Der iPod touch kommt mit Bildschirmlesefunktion und weiteren Bedienungshilfen
 
Lieferumfang
iPod touch, Ohrhörer, USB 2.0 Kabel, Dock Adapter, Kurzanleitung
";2;False;0;;;"Apple iPod touch 4G 64 GB ";apple-ipod-touch-4g-64-gb;True;True;PD-01068;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;359.9900;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40637,4565162037;45;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000615-apple-ipod-touch-4g-32-gb.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000616-apple-ipod-touch-4g-32-gb.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000617-apple-ipod-touch-4g-32-gb.jpg;1;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Apple iPod touch 4G 8 GB ";"Der neue iPod touch. Jetzt mit FaceTime, Retina Display, HD-Video und Game Center. ";"
Der neue iPod touch. Jetzt mit FaceTime, Retina Display, HD-Video und Game Center.
 
Spaß, hoch entwickelt. Der neue iPod touch.
Tonnen von innovativen Funktionen gibt es jetzt auch auf dem iPod touch. Einfach damit er noch mehr Spaß macht. Teilen Sie schöne Momente mit Freunden via FaceTime. Nehmen Sie Videos in HD auf. Oder erleben Sie Spiele auf dem höchstauflösenden iPod Display, das es je gab. Der iPod touch hat so viel Technologie, dass Sie glatt vergessen, dass es ein iPod ist.
 
Sieht unglaublich aus. Ist aber wahr.

Mit seinem neuen Design ist der iPod touch der dünnste, leichteste und fantastischste iPod touch, den es je gab. Um das zu spüren, müssen Sie ihn nur in die Hand nehmen. Er ist gerade mal 7,2 mm dünn. Mit seiner Vorderseite aus Hightech-Glas und der Rückseite aus Edelstahl fühlt er sich einfach fantastisch an. Wenn Sie ihn einschalten, sind Sie sofort vom brillanten Retina Display fasziniert. Der iPod touch kombiniert großartiges Design und revolutionäre Technologie - von außen wie von innen.
 
Retina Display. Die Zukunft sieht gut aus.
Es gibt viele Gründe, den iPod touch immer wieder anzusehen. Beispielsweise das LCD-Display mit 960 x 640 Pixeln und Hintergrundbeleuchtung. Es hat eine Pixeldichte von 326 ppi und ist damit das höchstauflösende iPod Display, das es je gab. Die Apple Ingenieure haben dafür superkleine, kaum 78 Mikrometer breite Pixel entwickelt, die das menschliche Auge nicht mehr als einzelne Pixel wahrnehmen kann. Und obwohl Sie sie nicht sehen können, werden Sie den Unterschied bemerken. Der Text ist gestochen scharf und alles sieht leuchtend und lebendig aus.
 
Apple A4 Prozessor. Mehr Power für Sie.
Hinter - oder besser gesagt unter - dem ganzen Spaß, den Sie mit dem iPod touch haben, steckt der Apple A4 Chip. Die Apple Ingenieure haben den A4 Chip als leistungsstarken und energieeffizienten Mobilprozessor entworfen. Damit bewältigt der iPod touch komplexe Aufgaben wie Multitasking, Videoschnitt und FaceTime Anrufe. All das bei noch mehr Batterielaufzeit. Und mehr Spaß.
 
Gyrosensor + Beschleunigungssensor. Wirklich bewegend.
Der iPod touch hat jetzt ein paar neue Tricks drauf. Er hat einen integrierten 3-Achsen-Gyrosensor, der zusammen mit dem Beschleunigungssensor dafür sorgt, dass der iPod touch Aktionen wie Beschleunigung, 3D Bewegung und Drehrate erkennt. Im Klartext: Mehr Bewegungen, mehr Gesten und größere Präzision für noch mehr Spielspaß.
 
Zwei Kameras. Doppelt so viel Spaß.
Für Videoaufnahmen hat der iPod touch zwei integrierte Kameras. Mit der Rückkamera nimmt er fantastische HD 720p Videos auf. Und der hoch entwickelte rückwärtig belichtete Sensor sorgt selbst bei schwacher Beleuchtung für tolle Aufnahmen. Das integrierte Mikrofon nimmt dabei gleichzeitig Gespräche, Musik oder alles andere auf. Die Frontkamera des iPod touch ist perfekt für FaceTime Anrufe1 und um sich selbst aufzunehmen. Schon erstaunlich, wie viel Spaß in etwas so Kleines passt.
Multi-Touch. Alles unter Kontrolle Ihrer.
Wie macht der iPod touch eigentlich genau das, was Sie wollen, wenn Sie mit Ihren Fingern über das Display streichen? Genau genommen ist es eine Kettenreaktion. Das Multi-Touch Display hat einen Schutzfilm über der kapazitiven Sensorik, die Berührungen anhand elektrischer Felder erkennt. Diese Informationen werden an das Retina Display darunter übermittelt. So könen Sie alles mit den Fingern steuern, mit Cover Flow in Ihren Alben blättern, Fotos sehen und vergrößern, in eine Website zoomen und Spiele steuern.
 
FaceTime auf dem iPod touch. Sagen Sie nicht einfach Hallo. Sagen Sie es mit einem Lächeln.
Ein Lächeln sagt mehr als tausend SMS.
Bringen Sie LOL auf die nächste Stufe und sehen Sie Ihre Freunde wirklich lachen. Oder lassen Sie XOXO lebendig werden und schicken Sie einen Kuss um die halbe Welt. FaceTime auf dem iPod touch macht's möglich. FaceTime funktioniert sofort nach dem Auspacken - Sie geben einfach Ihre Apple ID und E-Mail Adresse ein. Oder erstellen einen neuen E-Mail Account extra für FaceTime. FaceTime ist supereinfach. Stellen Sie sich vor, Sie wollen über Wi-Fi mit Ihrer besten Freundin videotelefonieren. Dann tippen Sie auf die FaceTime App, finden sie dort und starten den Anruf. Auf ihrem iPod touch oder iPhone 4 erscheint dann eine Einladung, die sie annehmen kann. Sobald sie annimmt, wird FaceTime gestartet. Das alles funktioniert ganz nahtlos und sowohl im Hoch- als auch im Querformat. Sie werden im wahrsten Sinne des Wortes sehen, wie viel Spaß Sie haben können.
 
Videotelefonieren Sie mit Freunden per FaceTime oder spielen Sie gegen Freunde oder Fremde mit Game Center.
 
Zwei Kameras für Spaß von jeder Seite.
Der iPod touch hat zwei Kameras - eine vorne über dem Display und eine auf der Rückseite. Die Frontkamera ist für FaceTime optimiert. Sie hat genau das richtige Sichtfeld und die richtige Brennweite, um auf die Entfernung einer Armlänge das Gesicht zu fokussieren. So zeigt sie Sie immer im besten Licht. Was besonders praktisch ist, wenn Sie mit jemandem sprechen, der mehr als nur ein Freund ist.
Die Rückkamera. Teilen Sie Ihre Ansicht.
Wenn Ihre Mitbewohnerin es doch nicht mehr zum Konzert schafft, lassen Sie sie mit FaceTime doch wenigstens die Zugabe sehen. Wenn die Band auf die Bühne kommt und ihren Lieblingshit spielt, tippen Sie einfach auf die Taste. Und noch bevor der Sänger die erste Zeile singt, wechselt der iPod touch zur Rückkamera und überträgt einen mit Sicherheit legendären Auftritt. Tippen Sie noch einmal und der iPod touch wechselt zurück auf die Frontkamera und zu Ihnen. Einfach und schnell - macht einfach Spaß!
 
HD Videoaufnahme auf dem iPod touch. Nehmen Sie jeden Spaß mit. Und auf.
 
Integrierter Schnittplatz.
Sie müssen mit dem Bearbeiten Ihrer Videos nicht warten, bis Sie wieder am Computer sitzen. Einfache Schnittfunktionen sind direkt im iPod touch integriert, sodass Sie gleich damit loslegen können. Ziehen Sie einfach, um Start- und Endpunkt des Films festzulegen. Behalten Sie nur die Teile des Videos, die Ihnen besonders gefallen, und machen Sie daraus einen Film, den Sie und Ihre Freunde immer und immer wieder anschauen wollen.
 
Mit iMovie auf dem iPod touch erstellen Sie Minikinofilmhits mit ein paar Fingertipps.
Stellen Sie sich vor, Sie sind unterwegs und wollen eine Videopostkarte erstellen, mit allem, was Sie erlebt und gesehen haben. Machen Sie das einfach mit der iMovie App - Sie bekommen sie im App Store. Mit iMovie für den iPod touch können Sie Videoclips zusammenfügen und bearbeiten, ihnen mit dynamischen Themen und Übergängen noch eine Extraportion Wow geben, Musik und Fotos hinzufügen und den fertigen Film mit allen teilen.
 
Drehen Sie einen Film. Mit Ihnen in der Hauptrolle.
Wenn Sie das nächste Mal eine aufregende Wanderung gemacht haben, erzählen Sie Ihren Freunden nicht nur davon - zeigen Sie es ihnen. Neben der HD Kamera auf der Rückseite besitzt der iPod touch eine Frontkamera mit VGA-Qualität über dem Display. So sehen Sie sich selbst, während Sie Videos aufnehmen. Das ist perfekt, um sich selbst zu filmen, denn Sie brauchen nicht mehr zu hoffen, dass Sie im Bild sind, sondern sehen es gleich. Also machen Sie sich bereit für die Aufnahme.
 
Teilen Sie mit Freunden den Rest Ihres Lebens.
Haben Sie auch schon mal eine Mail geschrieben und dabei etwas Unbeschreibliches gesehen? Dann nehmen Sie die Kamera und nehmen Sie es auf. Anschließend können Sie Ihren HD Film direkt auf YouTube laden. Oder wählen Sie ein Video aus den Aufnahmen und verschicken es mit einer Mail. Sie können es auch mit einem Fingertipp auf Ihre Facebook Seite oder in Ihren Blog posten. Und alle mit dem iPod touch aufgenommenen Videos ganz leicht mit Ihrem Mac oder PC synchronisieren.
So haben alle ein gutes Bild von Ihnen.

Eine unglaubliche Aussicht. Ein toller Kuchen. Ihr Hund, wie er soooooo süß schaut. Wenn Sie einen Schnappschuss für Facebook machen wollen, können Sie eine der beiden Kameras des iPod touch verwenden. Tippen Sie einfach auf das Display, um die Belichtung anzupassen. Dann posten Sie das Bild auf Facebook und warten auf die Kommentare.
 
Game Center. Spielen Sie gegen Ihre besten Feinde
Game Center. Mögen die Spiele beginnen.
Mit der neuen Game Center App auf dem iPod touch können Sie Ihr Spiele-Netzwerk erweitern. Exponentiell. Zum Spielen brauchen Sie nur einen iPod touch oder ein iPhone mit iOS 4.1. Bei iOS 4.1 wird eine Game Center App auf dem Homescreen angezeigt. Tippen Sie einfach darauf, meldes sich mit Ihrer Apple ID an und schon kann´s losgehen. Sie können einen Spielernamen erstellen, der für Ihre Freunde und die Spieler-Community sichtbar ist. Fügen Sie mehrere E-Mail Adressen zur Game Center App hinzu, damit Freunde Sie einfacher finden können. Sie können die Spiele über die Links im Game Center laden und auch direkt aus der Game Center App starten. Und das Beste: Sobald Sie sich bei Game Center anmelden, bleiben Sie verbunden. Bis Sie dich wieder abmelden.
 
Beste Freunde. Bald beste Gegner.
Treten Sie gegen Ihre Freunde in einem Rennen an. Oder einem Match. Oder in einem Kampf. Wenn Sie bei der Game Center App angemeldet sind, können Sie jemanden mit einer Freundschaftsanfrage einladen und dafür den Spielernamen oder die E-Mail Adresse der Person verwenden. Ihre Freunde erscheinen in einer separaten Freundeliste in der Game Center App. Tippen Sie auf die Namen von Freunden und Sie sehen, welche Spiele sie gespielt haben. Sie können auch neue Freundschaftsanfragen ansehen und eigene hinzufügen.
Leaderbords und Erfolge. Damit jeder sieht, wo Sie stehen.
Sehen Sie sich auf den Ranglisten für jedes Spiel Ihre Platzierung unter Ihren Freunden und anderen Spielern an. Sie können auch Ihre Erfolge mit denen Ihrer Freunde vergleichen. Sehen Sie sich die Leaderboards und Erfolge in der Game Center App und jedem einzelnen Spiel an. Und dann lassen Sie es krachen.
 
Trefen Sie Ihre Gegner. Und treffen Sie sie hart.
Sie möchten eine Runde mit mehreren Freunden spielen? Mit Auto-Match werden Ihnen zuerst Ihre Freunde als Gegner vorgeschlagen, wenn diese auch nach einem Auto-Match suchen. Wenn nicht, wird Ihnen ein Freund in spe irgendwo auf dem Globus als Gegner vorgeschlagen. Oder laden Sie Ihre Freunde ein und lassen Sie Auto-Match alle für ein Spiel benötigten Spieler finden.
Musik. Lassen Sie Ihre Finger tanzen.
Cover Flow. Musik sieht so gut aus.
Auf dem iPod touch gibt's Musik nicht nur auf die Ohren. Mit Cover Flow ist sie auch was für Augen und Finger. Drehen Sie den iPod touch auf die Seite und blättern Sie durch Ihre Albumcover. Tippen Sie auf ein Cover, um es umzudrehen und die Songliste zu sehen. Noch ein Tipp und die Musik läuft.
 
Genius Wiedergabelisten. In jedem guten Song steckt eine noch bessere Wiedergabeliste.
Angenommen Sie hören einen Song auf einem iPod touch, der Ihnen gut gefällt, und möchten weitere Titel hören, die gut dazu passen. Genius findet weitere Songs auf Ihrem iPod touch und erstellt eine Genius Wiedergabeliste. Hören Sie sich die Liste sofort an, speichern Sie sie für später oder versuchen's noch einmal und sehen, was dabei herauskommt. Verlassen Sie sich auf Genius, wenn Sie einen Mix wollen, auf den Sie selbst nie gekommen wären. 
 
Genius Mixe. Nehmen Sie den DJ mit nach Hause.
Genius ist Ihr persönlicher DJ. Synchronisieren Sie Ihren iPod touch mit iTunes und Genius durchsucht Ihre Mediathek automatisch nach Songs, die gut zusammenpassen. Dann erstellt Genius mehrere Mixe. Diese Mixe sind wie Radiosender, auf denen nur Ihre Lieblingshits laufen. So finden Sie Songs wieder, die Sie lange nicht mehr gehört haben oder von denen Sie gar nicht mehr wussten, dass Sie sie haben.
 
Lassen Sie Ihre Finger tanzen. 
 
Shake to shuffle. So ein Zufall.
Die Dinge mal aufrütteln. Musikalisch natürlich. Wenn Sie das nächste Mal Musik hören, aktivieren Sie einfach die Schüttelfunktion. Wenn Sie den iPod touch dann kurz schütteln, springt er nach dem Zufallsprinzip zu einem anderen Song in Ihrer Sammlung. So entdecken Sie Ihre Musik immer wieder neu.
 
iTunes. Das ist Entertainment.
Packen Sie Songs und Musikvideos aus Ihrer iTunes Mediathek auf dem Computer auf den iPod touch. Oder kaufen und laden Sie neue Songs auf den iPod touch, wenn Sie sich über Wi-Fi mit iTunes verbinden. Wenn Sie dann den iPod touch das nächste Mal mit dem Computer verbinden, werden alle Songs, die Sie auf dem iPod touch gekauft haben, auf den Mac oder PC übertragen. Und mit iTunes Ping können Sie jetzt sehen, welche Musik Ihre Freunde hören, kaufen und empfehlen. Oder informieren Sie sich dort über Ihre Lieblingskünstler und was sie so hören.
 
Bluetooth. Entfesseln Sie Ihre Musik.
Die Unterstützung für das drahtlose Bluetooth ist im iPod touch schon drin. Das heißt, Sie können drahtlose Stereokopfhörer verwenden. Lassen Sie den iPod in Ihrer Tasche stecken oder auf dem Schreibtisch aufladen, während Sie weiter Musik hören.
 
Filme und Fernsehsendungen. So haben Sie überall eine Sehenswürdigkeit.
Ganz großes Kino. Auf einem kleinen Display.
Mit dem iPod touch ist jeden Tag und überall Kinotag. Nehmen Sie Videos für viele Stunden Unterhaltung mit und sehen Sie sie auf dem fantastischen 3,5 Zoll Retina Display an. Kaufen Sie im iTunes Store und wählen Sie aus tausenden Filmen, Fernsehsendungen und Video-Podcasts für Ihren iPod touch. Da ist für jeden etwas dabei - von Hollywood Blockbustern bis zu Independent Filmen. Ein paar Fingertipps und Sie haben Filme geladen und können sie ansehen. Sie mögen lieber Fernsehsendungen? Die gibt's auch. Sie können einzelne Folgen oder gleich eine ganze Staffel kaufen. Mit dem iPod touch haben Sie Ihre Videos immer dabei.
Sie haben alles unter Kontrolle.
Wenn Sie ein Video schauen, tippen Sie einfach auf das Display und schon haben Sie die Steuerung. Damit können Sie die Wiedergabe starten oder unterbrechen, zu einzelnen Kapiteln springen und die Lautstärke anpassen. Oder verwenden Sie die Lautstärketasten links am iPod touch. Wenn Sie zwischen Widescreen- und Vollbildanzeige wechseln wollen, reicht ein Doppeltipp auf das Display. Das ist wie die Fernbedienung des Fernsehers. Nur, dass Sie nicht darum kämpfen müssen.
 
iTunes. Für beste Unterhaltung.
Sie brauchen für den nächsten Flug oder die nächste Fahrt etwas Unterhaltung? Mit iTunes auf dem iPod touch und einer Wi-Fi Verbindung können Sie sofort Filme und Fernsehsendungen kaufen. Oder Sie kaufen sie auf Ihrem Mac oder PC und synchronisieren sie mit dem iPod touch. Nur das Popcorn ist nicht dabei.
 
 
Besuchen Sie Ihre Lieblingswebsites. Alles, was Sie dazu brauchen, ist ein iPod touch und Wi-Fi. 
 
Laden Sie die iBooks App kostenlos und Sie haben nicht nur einen großartigen E-Book-Reader, sondern auch einen tollen Ort, um Bücher zu kaufen. 
 
Und vieles mehr...
 
App Store
Laden Sie Apps direkt auf den iPod touch
 
iTunes
Erstellen Sie einen iTunes Store Account und kaufen Sie jederzeit via Wi-Fi ein.
 
iBooks
Laden Sie die iBooks App kostenlos und Sie haben nicht nur einen großartigen E-Book-Reader, sondern auch einen tollen Ort, um Bücher zu kaufen.
 
iMovie
Bearbeiten Sie Videos, fügen Sie Themen und Musik hinzu und teilen Sie Ihre Filme mit Anderen
 
Mail
Senden Sie Mails und sehen Sie sich Anhänge von Ihrem Google Mail, MobileMe oder einem anderen E-Mail Account an.
 
Safari Webbrowser
Besuchen Sie Ihre Lieblingswebsites. Alles, was Sie dazu brauchen, ist ein iPod touch und Wi-Fi.
 
Fotos
Nehmen Sie Ihre Fotos mit. Teilen Sie sie per E-Mail. Wählen Sie Ihr Lieblingsfoto als Hintergrundbild.
 
Homescreen
Ordnen Sie in iTunes Ihre Apps auf mehreren Homescreens an.
 
 
Sprachsteuerung
Steuern Sie die Musik auf dem iPod touch mit Sprachbefehlen
 
Karten
Finden Sie Restaurants, Konzerte und mehr und lassen Sie sich mit Karten zeigen, wie Sie hinkommen.
 
YouTube
Sehen Sie sich die neuesten Videohits und Ihre Lieblingsvideos an.
 
Nike + iPod
Erreichen Sie Ihre Trainingsziele mit integrierter Unterstützung für Nike + iPod
 
Sprachmemos
Nehmen Sie Notizen, Gedanken oder alles andere auf.
 
Bedienungshilfen
Der iPod touch kommt mit Bildschirmlesefunktion und weiteren Bedienungshilfen
 
Lieferumfang
iPod touch, Ohrhörer, USB 2.0 Kabel, Dock Adapter, Kurzanleitung
";2;False;0;;;"Apple iPod touch 4G 8 GB ";apple-ipod-touch-4g-8-gb;True;True;PD-01067;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;209.9900;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40637,4560300926;45;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000615-apple-ipod-touch-4g-32-gb.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000616-apple-ipod-touch-4g-32-gb.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000617-apple-ipod-touch-4g-32-gb.jpg;1;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Apple iPod touch 4G 32 GB ";"Der neue iPod touch. Jetzt mit FaceTime, Retina Display, HD-Video und Game Center. ";"
Der neue iPod touch. Jetzt mit FaceTime, Retina Display, HD-Video und Game Center.
 
Spaß, hoch entwickelt. Der neue iPod touch.
Tonnen von innovativen Funktionen gibt es jetzt auch auf dem iPod touch. Einfach damit er noch mehr Spaß macht. Teilen Sie schöne Momente mit Freunden via FaceTime. Nehmen Sie Videos in HD auf. Oder erleben Sie Spiele auf dem höchstauflösenden iPod Display, das es je gab. Der iPod touch hat so viel Technologie, dass Sie glatt vergessen, dass es ein iPod ist.
 
Sieht unglaublich aus. Ist aber wahr.

Mit seinem neuen Design ist der iPod touch der dünnste, leichteste und fantastischste iPod touch, den es je gab. Um das zu spüren, müssen Sie ihn nur in die Hand nehmen. Er ist gerade mal 7,2 mm dünn. Mit seiner Vorderseite aus Hightech-Glas und der Rückseite aus Edelstahl fühlt er sich einfach fantastisch an. Wenn Sie ihn einschalten, sind Sie sofort vom brillanten Retina Display fasziniert. Der iPod touch kombiniert großartiges Design und revolutionäre Technologie - von außen wie von innen.
 
Retina Display. Die Zukunft sieht gut aus.
Es gibt viele Gründe, den iPod touch immer wieder anzusehen. Beispielsweise das LCD-Display mit 960 x 640 Pixeln und Hintergrundbeleuchtung. Es hat eine Pixeldichte von 326 ppi und ist damit das höchstauflösende iPod Display, das es je gab. Die Apple Ingenieure haben dafür superkleine, kaum 78 Mikrometer breite Pixel entwickelt, die das menschliche Auge nicht mehr als einzelne Pixel wahrnehmen kann. Und obwohl Sie sie nicht sehen können, werden Sie den Unterschied bemerken. Der Text ist gestochen scharf und alles sieht leuchtend und lebendig aus.
 
Apple A4 Prozessor. Mehr Power für Sie.
Hinter - oder besser gesagt unter - dem ganzen Spaß, den Sie mit dem iPod touch haben, steckt der Apple A4 Chip. Die Apple Ingenieure haben den A4 Chip als leistungsstarken und energieeffizienten Mobilprozessor entworfen. Damit bewältigt der iPod touch komplexe Aufgaben wie Multitasking, Videoschnitt und FaceTime Anrufe. All das bei noch mehr Batterielaufzeit. Und mehr Spaß.
 
Gyrosensor + Beschleunigungssensor. Wirklich bewegend.
Der iPod touch hat jetzt ein paar neue Tricks drauf. Er hat einen integrierten 3-Achsen-Gyrosensor, der zusammen mit dem Beschleunigungssensor dafür sorgt, dass der iPod touch Aktionen wie Beschleunigung, 3D Bewegung und Drehrate erkennt. Im Klartext: Mehr Bewegungen, mehr Gesten und größere Präzision für noch mehr Spielspaß.
 
Zwei Kameras. Doppelt so viel Spaß.
Für Videoaufnahmen hat der iPod touch zwei integrierte Kameras. Mit der Rückkamera nimmt er fantastische HD 720p Videos auf. Und der hoch entwickelte rückwärtig belichtete Sensor sorgt selbst bei schwacher Beleuchtung für tolle Aufnahmen. Das integrierte Mikrofon nimmt dabei gleichzeitig Gespräche, Musik oder alles andere auf. Die Frontkamera des iPod touch ist perfekt für FaceTime Anrufe1 und um sich selbst aufzunehmen. Schon erstaunlich, wie viel Spaß in etwas so Kleines passt.
Multi-Touch. Alles unter Kontrolle Ihrer.
Wie macht der iPod touch eigentlich genau das, was Sie wollen, wenn Sie mit Ihren Fingern über das Display streichen? Genau genommen ist es eine Kettenreaktion. Das Multi-Touch Display hat einen Schutzfilm über der kapazitiven Sensorik, die Berührungen anhand elektrischer Felder erkennt. Diese Informationen werden an das Retina Display darunter übermittelt. So könen Sie alles mit den Fingern steuern, mit Cover Flow in Ihren Alben blättern, Fotos sehen und vergrößern, in eine Website zoomen und Spiele steuern.
 
FaceTime auf dem iPod touch. Sagen Sie nicht einfach Hallo. Sagen Sie es mit einem Lächeln.
Ein Lächeln sagt mehr als tausend SMS.
Bringen Sie LOL auf die nächste Stufe und sehen Sie Ihre Freunde wirklich lachen. Oder lassen Sie XOXO lebendig werden und schicken Sie einen Kuss um die halbe Welt. FaceTime auf dem iPod touch macht's möglich. FaceTime funktioniert sofort nach dem Auspacken - Sie geben einfach Ihre Apple ID und E-Mail Adresse ein. Oder erstellen einen neuen E-Mail Account extra für FaceTime. FaceTime ist supereinfach. Stellen Sie sich vor, Sie wollen über Wi-Fi mit Ihrer besten Freundin videotelefonieren. Dann tippen Sie auf die FaceTime App, finden sie dort und starten den Anruf. Auf ihrem iPod touch oder iPhone 4 erscheint dann eine Einladung, die sie annehmen kann. Sobald sie annimmt, wird FaceTime gestartet. Das alles funktioniert ganz nahtlos und sowohl im Hoch- als auch im Querformat. Sie werden im wahrsten Sinne des Wortes sehen, wie viel Spaß Sie haben können.
 
Videotelefonieren Sie mit Freunden per FaceTime oder spielen Sie gegen Freunde oder Fremde mit Game Center.
 
Zwei Kameras für Spaß von jeder Seite.
Der iPod touch hat zwei Kameras - eine vorne über dem Display und eine auf der Rückseite. Die Frontkamera ist für FaceTime optimiert. Sie hat genau das richtige Sichtfeld und die richtige Brennweite, um auf die Entfernung einer Armlänge das Gesicht zu fokussieren. So zeigt sie Sie immer im besten Licht. Was besonders praktisch ist, wenn Sie mit jemandem sprechen, der mehr als nur ein Freund ist.
Die Rückkamera. Teilen Sie Ihre Ansicht.
Wenn Ihre Mitbewohnerin es doch nicht mehr zum Konzert schafft, lassen Sie sie mit FaceTime doch wenigstens die Zugabe sehen. Wenn die Band auf die Bühne kommt und ihren Lieblingshit spielt, tippen Sie einfach auf die Taste. Und noch bevor der Sänger die erste Zeile singt, wechselt der iPod touch zur Rückkamera und überträgt einen mit Sicherheit legendären Auftritt. Tippen Sie noch einmal und der iPod touch wechselt zurück auf die Frontkamera und zu Ihnen. Einfach und schnell - macht einfach Spaß!
 
HD Videoaufnahme auf dem iPod touch. Nehmen Sie jeden Spaß mit. Und auf.
 
Integrierter Schnittplatz.
Sie müssen mit dem Bearbeiten Ihrer Videos nicht warten, bis Sie wieder am Computer sitzen. Einfache Schnittfunktionen sind direkt im iPod touch integriert, sodass Sie gleich damit loslegen können. Ziehen Sie einfach, um Start- und Endpunkt des Films festzulegen. Behalten Sie nur die Teile des Videos, die Ihnen besonders gefallen, und machen Sie daraus einen Film, den Sie und Ihre Freunde immer und immer wieder anschauen wollen.
 
Mit iMovie auf dem iPod touch erstellen Sie Minikinofilmhits mit ein paar Fingertipps.
Stellen Sie sich vor, Sie sind unterwegs und wollen eine Videopostkarte erstellen, mit allem, was Sie erlebt und gesehen haben. Machen Sie das einfach mit der iMovie App - Sie bekommen sie im App Store. Mit iMovie für den iPod touch können Sie Videoclips zusammenfügen und bearbeiten, ihnen mit dynamischen Themen und Übergängen noch eine Extraportion Wow geben, Musik und Fotos hinzufügen und den fertigen Film mit allen teilen.
 
Drehen Sie einen Film. Mit Ihnen in der Hauptrolle.
Wenn Sie das nächste Mal eine aufregende Wanderung gemacht haben, erzählen Sie Ihren Freunden nicht nur davon - zeigen Sie es ihnen. Neben der HD Kamera auf der Rückseite besitzt der iPod touch eine Frontkamera mit VGA-Qualität über dem Display. So sehen Sie sich selbst, während Sie Videos aufnehmen. Das ist perfekt, um sich selbst zu filmen, denn Sie brauchen nicht mehr zu hoffen, dass Sie im Bild sind, sondern sehen es gleich. Also machen Sie sich bereit für die Aufnahme.
 
Teilen Sie mit Freunden den Rest Ihres Lebens.
Haben Sie auch schon mal eine Mail geschrieben und dabei etwas Unbeschreibliches gesehen? Dann nehmen Sie die Kamera und nehmen Sie es auf. Anschließend können Sie Ihren HD Film direkt auf YouTube laden. Oder wählen Sie ein Video aus den Aufnahmen und verschicken es mit einer Mail. Sie können es auch mit einem Fingertipp auf Ihre Facebook Seite oder in Ihren Blog posten. Und alle mit dem iPod touch aufgenommenen Videos ganz leicht mit Ihrem Mac oder PC synchronisieren.
So haben alle ein gutes Bild von Ihnen.

Eine unglaubliche Aussicht. Ein toller Kuchen. Ihr Hund, wie er soooooo süß schaut. Wenn Sie einen Schnappschuss für Facebook machen wollen, können Sie eine der beiden Kameras des iPod touch verwenden. Tippen Sie einfach auf das Display, um die Belichtung anzupassen. Dann posten Sie das Bild auf Facebook und warten auf die Kommentare.
 
Game Center. Spielen Sie gegen Ihre besten Feinde
Game Center. Mögen die Spiele beginnen.
Mit der neuen Game Center App auf dem iPod touch können Sie Ihr Spiele-Netzwerk erweitern. Exponentiell. Zum Spielen brauchen Sie nur einen iPod touch oder ein iPhone mit iOS 4.1. Bei iOS 4.1 wird eine Game Center App auf dem Homescreen angezeigt. Tippen Sie einfach darauf, meldes sich mit Ihrer Apple ID an und schon kann´s losgehen. Sie können einen Spielernamen erstellen, der für Ihre Freunde und die Spieler-Community sichtbar ist. Fügen Sie mehrere E-Mail Adressen zur Game Center App hinzu, damit Freunde Sie einfacher finden können. Sie können die Spiele über die Links im Game Center laden und auch direkt aus der Game Center App starten. Und das Beste: Sobald Sie sich bei Game Center anmelden, bleiben Sie verbunden. Bis Sie dich wieder abmelden.
 
Beste Freunde. Bald beste Gegner.
Treten Sie gegen Ihre Freunde in einem Rennen an. Oder einem Match. Oder in einem Kampf. Wenn Sie bei der Game Center App angemeldet sind, können Sie jemanden mit einer Freundschaftsanfrage einladen und dafür den Spielernamen oder die E-Mail Adresse der Person verwenden. Ihre Freunde erscheinen in einer separaten Freundeliste in der Game Center App. Tippen Sie auf die Namen von Freunden und Sie sehen, welche Spiele sie gespielt haben. Sie können auch neue Freundschaftsanfragen ansehen und eigene hinzufügen.
Leaderbords und Erfolge. Damit jeder sieht, wo Sie stehen.
Sehen Sie sich auf den Ranglisten für jedes Spiel Ihre Platzierung unter Ihren Freunden und anderen Spielern an. Sie können auch Ihre Erfolge mit denen Ihrer Freunde vergleichen. Sehen Sie sich die Leaderboards und Erfolge in der Game Center App und jedem einzelnen Spiel an. Und dann lassen Sie es krachen.
 
Trefen Sie Ihre Gegner. Und treffen Sie sie hart.
Sie möchten eine Runde mit mehreren Freunden spielen? Mit Auto-Match werden Ihnen zuerst Ihre Freunde als Gegner vorgeschlagen, wenn diese auch nach einem Auto-Match suchen. Wenn nicht, wird Ihnen ein Freund in spe irgendwo auf dem Globus als Gegner vorgeschlagen. Oder laden Sie Ihre Freunde ein und lassen Sie Auto-Match alle für ein Spiel benötigten Spieler finden.
Musik. Lassen Sie Ihre Finger tanzen.
Cover Flow. Musik sieht so gut aus.
Auf dem iPod touch gibt's Musik nicht nur auf die Ohren. Mit Cover Flow ist sie auch was für Augen und Finger. Drehen Sie den iPod touch auf die Seite und blättern Sie durch Ihre Albumcover. Tippen Sie auf ein Cover, um es umzudrehen und die Songliste zu sehen. Noch ein Tipp und die Musik läuft.
 
Genius Wiedergabelisten. In jedem guten Song steckt eine noch bessere Wiedergabeliste.
Angenommen Sie hören einen Song auf einem iPod touch, der Ihnen gut gefällt, und möchten weitere Titel hören, die gut dazu passen. Genius findet weitere Songs auf Ihrem iPod touch und erstellt eine Genius Wiedergabeliste. Hören Sie sich die Liste sofort an, speichern Sie sie für später oder versuchen's noch einmal und sehen, was dabei herauskommt. Verlassen Sie sich auf Genius, wenn Sie einen Mix wollen, auf den Sie selbst nie gekommen wären. 
 
Genius Mixe. Nehmen Sie den DJ mit nach Hause.
Genius ist Ihr persönlicher DJ. Synchronisieren Sie Ihren iPod touch mit iTunes und Genius durchsucht Ihre Mediathek automatisch nach Songs, die gut zusammenpassen. Dann erstellt Genius mehrere Mixe. Diese Mixe sind wie Radiosender, auf denen nur Ihre Lieblingshits laufen. So finden Sie Songs wieder, die Sie lange nicht mehr gehört haben oder von denen Sie gar nicht mehr wussten, dass Sie sie haben.
 
Lassen Sie Ihre Finger tanzen. 
 
Shake to shuffle. So ein Zufall.
Die Dinge mal aufrütteln. Musikalisch natürlich. Wenn Sie das nächste Mal Musik hören, aktivieren Sie einfach die Schüttelfunktion. Wenn Sie den iPod touch dann kurz schütteln, springt er nach dem Zufallsprinzip zu einem anderen Song in Ihrer Sammlung. So entdecken Sie Ihre Musik immer wieder neu.
 
iTunes. Das ist Entertainment.
Packen Sie Songs und Musikvideos aus Ihrer iTunes Mediathek auf dem Computer auf den iPod touch. Oder kaufen und laden Sie neue Songs auf den iPod touch, wenn Sie sich über Wi-Fi mit iTunes verbinden. Wenn Sie dann den iPod touch das nächste Mal mit dem Computer verbinden, werden alle Songs, die Sie auf dem iPod touch gekauft haben, auf den Mac oder PC übertragen. Und mit iTunes Ping können Sie jetzt sehen, welche Musik Ihre Freunde hören, kaufen und empfehlen. Oder informieren Sie sich dort über Ihre Lieblingskünstler und was sie so hören.
 
Bluetooth. Entfesseln Sie Ihre Musik.
Die Unterstützung für das drahtlose Bluetooth ist im iPod touch schon drin. Das heißt, Sie können drahtlose Stereokopfhörer verwenden. Lassen Sie den iPod in Ihrer Tasche stecken oder auf dem Schreibtisch aufladen, während Sie weiter Musik hören.
 
Filme und Fernsehsendungen. So haben Sie überall eine Sehenswürdigkeit.
Ganz großes Kino. Auf einem kleinen Display.
Mit dem iPod touch ist jeden Tag und überall Kinotag. Nehmen Sie Videos für viele Stunden Unterhaltung mit und sehen Sie sie auf dem fantastischen 3,5 Zoll Retina Display an. Kaufen Sie im iTunes Store und wählen Sie aus tausenden Filmen, Fernsehsendungen und Video-Podcasts für Ihren iPod touch. Da ist für jeden etwas dabei - von Hollywood Blockbustern bis zu Independent Filmen. Ein paar Fingertipps und Sie haben Filme geladen und können sie ansehen. Sie mögen lieber Fernsehsendungen? Die gibt's auch. Sie können einzelne Folgen oder gleich eine ganze Staffel kaufen. Mit dem iPod touch haben Sie Ihre Videos immer dabei.
Sie haben alles unter Kontrolle.
Wenn Sie ein Video schauen, tippen Sie einfach auf das Display und schon haben Sie die Steuerung. Damit können Sie die Wiedergabe starten oder unterbrechen, zu einzelnen Kapiteln springen und die Lautstärke anpassen. Oder verwenden Sie die Lautstärketasten links am iPod touch. Wenn Sie zwischen Widescreen- und Vollbildanzeige wechseln wollen, reicht ein Doppeltipp auf das Display. Das ist wie die Fernbedienung des Fernsehers. Nur, dass Sie nicht darum kämpfen müssen.
 
iTunes. Für beste Unterhaltung.
Sie brauchen für den nächsten Flug oder die nächste Fahrt etwas Unterhaltung? Mit iTunes auf dem iPod touch und einer Wi-Fi Verbindung können Sie sofort Filme und Fernsehsendungen kaufen. Oder Sie kaufen sie auf Ihrem Mac oder PC und synchronisieren sie mit dem iPod touch. Nur das Popcorn ist nicht dabei.
 
 
Besuchen Sie Ihre Lieblingswebsites. Alles, was Sie dazu brauchen, ist ein iPod touch und Wi-Fi. 
 
Laden Sie die iBooks App kostenlos und Sie haben nicht nur einen großartigen E-Book-Reader, sondern auch einen tollen Ort, um Bücher zu kaufen. 
 
Und vieles mehr...
 
App Store
Laden Sie Apps direkt auf den iPod touch
 
iTunes
Erstellen Sie einen iTunes Store Account und kaufen Sie jederzeit via Wi-Fi ein.
 
iBooks
Laden Sie die iBooks App kostenlos und Sie haben nicht nur einen großartigen E-Book-Reader, sondern auch einen tollen Ort, um Bücher zu kaufen.
 
iMovie
Bearbeiten Sie Videos, fügen Sie Themen und Musik hinzu und teilen Sie Ihre Filme mit Anderen
 
Mail
Senden Sie Mails und sehen Sie sich Anhänge von Ihrem Google Mail, MobileMe oder einem anderen E-Mail Account an.
 
Safari Webbrowser
Besuchen Sie Ihre Lieblingswebsites. Alles, was Sie dazu brauchen, ist ein iPod touch und Wi-Fi.
 
Fotos
Nehmen Sie Ihre Fotos mit. Teilen Sie sie per E-Mail. Wählen Sie Ihr Lieblingsfoto als Hintergrundbild.
 
Homescreen
Ordnen Sie in iTunes Ihre Apps auf mehreren Homescreens an.
 
 
Sprachsteuerung
Steuern Sie die Musik auf dem iPod touch mit Sprachbefehlen
 
Karten
Finden Sie Restaurants, Konzerte und mehr und lassen Sie sich mit Karten zeigen, wie Sie hinkommen.
 
YouTube
Sehen Sie sich die neuesten Videohits und Ihre Lieblingsvideos an.
 
Nike + iPod
Erreichen Sie Ihre Trainingsziele mit integrierter Unterstützung für Nike + iPod
 
Sprachmemos
Nehmen Sie Notizen, Gedanken oder alles andere auf.
 
Bedienungshilfen
Der iPod touch kommt mit Bildschirmlesefunktion und weiteren Bedienungshilfen
 
Lieferumfang
iPod touch, Ohrhörer, USB 2.0 Kabel, Dock Adapter, Kurzanleitung
";2;False;0;;;"Apple iPod touch 4G 32 GB ";apple-ipod-touch-4g-32-gb;True;True;PD-01066;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;279.9900;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40637,445775463;45;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000615-apple-ipod-touch-4g-32-gb.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000616-apple-ipod-touch-4g-32-gb.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000617-apple-ipod-touch-4g-32-gb.jpg;1;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Apple iPod shuffle 2 GB 4G;"Der neue, bunte, tragbare iPod shuffle. Mit Tasten, VoiceOver und Wiedergabelisten - der beste iPod shuffle, den es je gab. ";"Der neue, bunte, tragbare iPod shuffle.
Mit Tasten, VoiceOver und Wiedergabelisten - der beste iPod shuffle, den es je gab.
 
Eingebauter Clip.

Sie ist wieder da - die große Klickbedienung vorn auf dem iPod shuffle.
 
Erhältlich in Silber, Blau, Grün, Orange und Pink.
 
Design. Ganz schön ansteckend.
Elegantes, poliertes Aluminium. Fünf leuchtende Farben.
Das Gehäuse des iPod shuffle ist aus einem Stück Aluminium. Und weil es außerdem poliert ist, können Sie mit dem neuen, eleganten und robusten iPod shuffle richtig glänzen. Seine brillanten Farben machen ihn dabei zum perfekten Accessoire. Wählen Sie zwischen Silber, Blau, Grün, Orange und Pink.
 
Hunderte Songs für unterwegs.
Nehmen Sie Ihre Lieblingssongs überallhin mit. Neben 15 Stunden Batterielaufzeit1 kommt der iPod shuffle mit 2 GB Speicher - das heißt Platz für hunderte von Songs. Genug für alle Songs für Ihr Fitness-Training oder den Weg zur Arbeit. Und auch für mehrere Wiedergabelisten, Genius Mixe, Podcasts und Hörbücher.
 
Geht immer. Und überall.
Der iPod shuffle ist nicht nur tragbar. Er ist auch ansteckbar. Klippen Sie ihn an Hemd, Jacke, Jogginghose, Rucksack oder Tasche und er ist überall mit dabei - egal, ob Sie zum Supermarkt laufen oder zu Ihrer persönlichen Bestzeit.
 
Bedienung. Musik auf Knopfdruck.

Steuern Sie Ihre Musik mit nur einem Klick.
Sie ist wieder da - die große Klickbedienung vorn auf dem iPod shuffle. Sie ist 18 Prozent größer als bei den Vorgängermodellen. So können Sie sie sie noch leichter sehen und bedienen. Drücken Sie auf die Mitteltaste, um die Wiedergabe zu starten oder zu stoppen. Drücken Sie auf die äußeren Tasten, um vor- und zurückzuspringen oder die Lautstärke anzupassen. Klick, klick, klick. Das ist Musik für Ihre Finger.
 
Spielt nach Ihren Regeln.
Sie sind eher ein spontaner Typ? Oder haben Sie vielleicht lieber Ihre Ordnung? Stellen Sie den Schalter für die Zufallswiedergabe so ein, wie Sie wollen. Links wird Ihre Musik zufällig durcheinander gewürfelt. In der Mitte werden Ihre Songs in der normalen Reihenfolge gespielt. Und rechts schalten Sie den iPod shuffle aus.
 
Geben Sie Ihren Songs eine Stimme.
Angenommen Sie hören einen Song und wollen den Titel oder den Interpreten wissen. Drücken Sie einfach oben auf deinem iPod shuffle auf die neue VoiceOver Taste und VoiceOver nennt Ihnen beides. VoiceOver nennt Ihnen auch die Namen Ihrer Wiedergabelisten und wechselt zwischen diesen. Und wenn die Batterie aufgeladen werden muss, sagt VoiceOver das auch.
 
Spricht Ihre Sprache.
Französische Chansons. Spanische Flamencos. Italienische Arien. Ihr Musikarchiv enthält Songs aus allen Ländern der Erde. Deshalb spricht VoiceOver 25 verschiedene Sprachen. Und kann Ihnen Songtitel und Interpreten in deren jeweiliger Landessprache oder einer anderen Sprache nennen.
 
Wiedergabelisten. Der perfekte Mix für jede Stimmung.
Ganz einfach synchronisieren.
Mit iTunes auf dem Mac oder PC können Sie Ihre Sachen ganz einfach auf den iPod shuffle laden. Wählen Sie einfach die Hörbücher, Wiedergabelisten, Podcasts und andere Audiodateien, die Sie wollen, und synchronisieren Sie sie.
 
Wenn eine Wiedergabeliste nicht reicht.

Wahrscheinlich haben Sie in iTunes auf Ihrem Computer mehrere Wiedergabelisten. Eine für unterwegs. Eine fürs Fitnessstudio. Eine zum Chillen. Jetzt können Sie diese Wiedergabelisten mit dem iPod shuffle synchronisieren und haben immer genau den richtigen Mix - egal, in welcher Stimmung Sie gerade sind. VoiceOver nennt Ihnen den Namen jeder Wiedergabeliste. So können Sie ganz leicht zwischen ihnen wechseln und genau die auswählen, nach der Ihnen gerade ist.
 
Genius auf dem iPod shuffle.

Und es gibt noch einen anderen Weg einen guten Mix auf den iPod shuffle zu bekommen: Verlassen Sie sich auf Genius. Aktivieren Sie Genius in iTunes auf dem Computer und er findet automatisch Songs, die gut zusammenpassen. Dann werden Genius Mixe erstellt, die Sie ganz einfach mit Ihrem iPod shuffle synchronisieren können. Das ist perfekt, um Songs zu entdecken, die Sie schon seit Jahrhunderten nicht mehr gehört haben.
 
Lieferumfang
iPod shuffle, Ohrhörer, iPod shuffle USB Kabel (4,5 cm), Dokumentation";2;False;0;;;Apple iPod shuffle 2 GB 4G;apple-ipod-shuffle-2-gb-4g;True;True;PD-01065;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;54.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40637,4367824074;41;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000600-apple-ipod-shuffle-2-gb-4g.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000601-apple-ipod-shuffle-2-gb-4g.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000602-apple-ipod-shuffle-2-gb-4g.jpg;1;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Nokia Lumia 800 Smartphone;Nokia Lumia 800 Smartphone (9,4 cm (3.7 Zoll) AMOLED Clear Black-Touchscreen, Micro-SIM only, Windows Phone Mango OS, 8 MP Kamera) schwarz;"
Einfacher ist besser.
Das Nokia Lumia 800 mit Windows Phone. Alle Aktivitäten Ihrer Kontakte auf einen Blick.
 
Startseite
Legen Sie Gruppen oder Kontakte auf der Startseite ab, um noch schneller auf sie zuzugreifen. Sie können beliebige Elemente auf der Startseite ablegen. Halten Sie einfach den Finger auf die gewünschten Apps oder Tools, bis das Menü „Auf Startseite“ angezeigt wird.
 
Gruppen
Die Gruppe „Familie“ ist im Kontakte-Hub vorkonfiguriert, damit Sie sofort loslegen können. Sie schlägt Ihnen Kontakte mit übereinstimmenden Namen als Gruppenmitglieder vor. Doch Sie können auch beliebige andere Gruppen als Kachel auf der Startseite ablegen. In diesen Kacheln werden Profilfotos, entgangene Anrufe und Status-Updates aller Kontakte dieser Gruppe anzeigt. Sofort nach einer Status-Änderung beginnt diese Kachel, sich in sich selbst zu drehen, damit Sie keine Nachricht mehr verpassen. Wenn Sie Ihre Kontakte leichter voneinander unterscheiden möchten, können Sie ihnen individuell oder als Gruppe eigene Klingeltöne zuweisen. Tippen Sie einfach auf das gewünschte Profil und dann auf das Stift-Symbol, um einen Klingelton zu bearbeiten und hinzuzufügen.
 
Immer tolle Fotos
Fotografieren war noch nie so einfach – betätigen Sie einfach den Auslöser. Sie müssen das Smartphone noch nicht einmal entsperren, um richtig tolle Fotos zu machen. Danach können Sie die Fotos ebenso schnell auf Facebook oder anderen sozialen Netzwerken veröffentlichen. Und die 5-Megapixel-Kamera mit Autofokus sorgt für brillante, detailreiche Fotos, die garantiert Eindruck machen.
 
Sprachgesteuerte Aktivierung
Halten Sie einfach die Windows-Taste gedrückt, um die Spracherkennung zu aktivieren. Sie können mithilfe von Sprachbefehlen Anrufe tätigen, Ihren Kalender aufrufen, Texte diktieren und sogar Internetrecherchen durchführen.
 
Multitasking
Halten Sie den Zurück-Pfeil gedrückt, um zu sehen, welche Anwendungen gleichzeitig ausgeführt werden. Profil
Nokia Lumia Smartphones sind automatisch mit Facebook verknüpft und verwenden Ihr Standard-Profilbild. Doch auch das können Sie im Handumdrehen ändern – tippen Sie einfach auf „Profil“, um ein neues Foto auszuwählen.
 
Nokia Lumia Smartphones und Bing
Starten Sie die Anwendung im Handumdrehen über das Symbol „Suchen“, um Internetrecherchen durchführen zu können, ohne den Browser zu öffnen. Geben Sie einfach Ihren Suchbegriff ein und wählen Sie das beste Ergebnis. Einfach. Intuitiv. Schnell.
 
Apps
Mit Wi-Fi laden Sie Apps mit größerem Dateiumfang, mobile Spiele und Medien noch schneller herunter. So können Sie das von Ihrem Provider ggf. im Rahmen eines Vertrags zur Verfügung gestellte Dateivolumen genau dann nutzen, wenn Sie es wirklich benötigen.
 
Xbox Live Avatar
In Xbox Live erstellen Sie ganz leicht einen Avatar für die Xbox Community. Öffnen Sie einfach Xbox Live und klicken Sie auf „Avatar“. Dort können Sie Ihrer Figur je nach Wunsch Frisur, Gesichtszüge und Kleider geben - auch als Abbild Ihrer selbst. Eben einfach die vielen kleinen Dinge, die Sie unverwechselbar machen. Lassen Sie Ihrer Kreativität freien Lauf und freuen Sie sich auf rasantes Gaming.
 
Musik kaufen
Mit Millionen von Songs zur Auswahl bietet Ihnen Nokia Musik jederzeit Zugriff auf die neuesten Hits und Ihre Lieblings-Klassiker. Nutzen Sie einfach die Suchfunktion oder stöbern Sie in den neuesten Veröffentlichungen. Wenn Sie sich entschieden haben, genügt eine Berührung, um den Song zu kaufen und in Ihre Bibliothek herunterzuladen.
 
Schnelle Steuerung
Wahrscheinlich möchten Sie noch mehr tun, als nur Musik zu hören. Deshalb ist es gut, dass Sie nicht jedes Mal Nokia Musik öffnen müssen, um zu einem anderen Song zu wechseln. Tippen Sie einfach auf die Lautstärkeregelung und unterbrechen oder überspringen Sie Songs über den Schnellzugriff. Das funktioniert auch, wenn das Smartphone gesperrt ist.
 
Aktuelle Wiedergabe
Über die Wiedergabeliste können Sie Musik aus Ihrer Bibliothek jederzeit individuell steuern - beispielsweise als zufällige Wiedergabe oder als Dauerschleife.
 
Sprachgestützte Navigation
Die Nokia Navigation mit gesprochenen Richtungsanweisungen ist auf Ihrem Nokia Lumia Smartphone vorinstalliert. Ihnen gefällt die Stimme nicht? Dann ändern Sie einfach die Ansagestimme der Navigation oder laden Sie eine neue herunter. Öffnen Sie dazu die Einstellungen und wählen Sie die Stimme, die Ihnen am angenehmsten ist.
 
Tag und Nacht
Sie werden bei Nachtfahrten nie wieder durch Ihr Navigationssystem geblendet. Mit der Nokia Navigation können Sie die Helligkeit des Displays anpassen, ohne dadurch die Deutlichkeit der Anzeige zu beeinträchtigen.
 
2D und 3D
Die Nokia Navigation bietet sowohl 2D- als auch 3D-Kartenansichten. Wenn Sie also eine genauere Ansicht Ihrer Route benötigen oder nach einprägsamen Orientierungspunkten Ausschau halten möchten, können Sie die Ansicht einfach über die Einstellungen ändern.
 
Nokia Karten herunterladen
Nokia Karten ist nach wenigen Handgriffen auf Ihrem Smartphone einsatzbereit. Diese App beinhaltet kostenlose Reiseführer, Veranstaltungstipps, interessante Ziele in Ihrer Nähe, Wetterinfos und vieles mehr. Öffnen Sie die Karten-Kachel, rufen Sie Marketplace auf und starten Sie den Download – die Anwendung ist kostenlos. Nach der Installation können Sie Nokia Karten über 3G- oder WLAN-Verbindungen nutzen.
";2;False;0;;;Nokia Lumia 800 Smartphone;nokia-lumia-800-smartphone;True;True;P-0006;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;499.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40603,5677546296;"74;2095";17;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000534-nokia-lumia-800-smartphone.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000535-nokia-lumia-800-smartphone.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000536-nokia-lumia-800-smartphone.jpg;1;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Nokia N9 Smartphone blau;Nokia N9 Smartphone (9,9 cm (3,9 Zoll) Display, 16GB, Touchscreen, 8 Megapixel Kamera) blau;"
Nokia N9 Smartphone
Formatfüllender Touchscreen
Ein einzigartiges Smartphone mit formatfüllendem Touchscreen. Die gewölbte Oberfläche aus kratzfestem Glas geht nahtlos in das glatte, aus einem Block gefertigte Gehäuse über. Jedes Detail strahlt Innovation aus. Auf dem brillanten AMOLED-Touchscreen erscheint alles in lebendigen Farben und das gewölbte Glas macht den Wechsel zwischen Apps per Fingerbewegung zum Kinderspiel.
 
Einfach nur eine Fingerbewegung - Überzeugend benutzerfreundlich
Alles läuft auf eine einfache Fingerbewegung hinaus. Das macht die Nutzung dieses Smartphones so intuitiv wie nie zuvor. Es gibt keine Zurück- oder Menü-Taste mehr – nur fliessende Fingerbewegungen, während Sie von App zu App wechseln. Mit einer Fingerbewegung über eine beliebige Ecke des Touchscreens gelangen Sie zur Startansicht, mit einer weiteren Bewegung wechseln Sie zwischen den drei Startansichten.
 
Eine Startansicht - Drei einfache Ansichten
Drei Ansichten sind alles, was Sie brauchen. In der vertrauten App-Ansicht starten Sie Anwendungen, eine weitere Ansicht zeigt die offenen Apps und macht Multitasking zum Kinderspiel: Sie machen genau dort weiter, wo Sie aufgehört haben.- Die Ansicht ""Ereignisse"" bringt Sie jederzeit auf den neuesten Stand der Dinge. Live-Feeds von Facebook und Twitter, E-Mails in Echtzeit, RSS-Feeds und mehr – alles an einer Stelle.
 
Karten und Navigation kostenlos
Live-Feeds von Facebook und Twitter, E-Mails in Echtzeit, RSS-Feeds und mehr – alles an einer Stelle. Sie finden die besten Angebote in Ihrer Stadt wie Cafés, Geschäfte, Konzerte, Hotels und mehr. Für mehr als 80 Städte weltweit steht Ihnen eine Übersicht von Strecken und Haltestellen des öffentlichen Nahverkehrs zur Verfügung. Entsprechendes Kartenmaterial ist bereits vorinstalliert, sodass Sie sofort starten können. Die Anwendung ""Fahren"" ist dank einfacher Bedienung über Touchscreen für die Verwendung im Auto optimiert.
 
Browser der nächsten Generation
Zeit für mehr Tempo. Das Nokia N9 bietet einen schnellen mobilen Internet-Browser und Seiten werden in kürzester Zeit aufgebaut. Die Unterstützung für HTML5 bedeutet für Sie das Beste aus dem Web, inklusive interaktiver Apps und schneller Videowiedergabe. Der Browser reagiert schnell auf jede Berührung. Sie können mehrere Seiten gleichzeitig öffnen und schnell zwischen den Seiten wechseln.
 
 
 
8-Megapixel-Kamera mit Optik von Carl Zeiss
Die Gelegenheit für ein gutes Foto kommt schnell und ist ebenso schnell vorbei. Mit der integrierten 8-Megapixel-Kamera mit Optik von Carl Zeiss können Sie brillante Fotos oder Videos in herausragender HD-Qualität aufnehmen.
 
Die besten Apps und Spiele
Apps sind heutzutage allgegenwärtig. Das Wichtigste ist jedoch die Qualität und nicht, wie viele man besitzt. Auf dem Nokia N9 sind die besten Apps wie Skype, Facebook, Twitter, AccuWeather und AP Mobile bereits vorinstalliert. Auch die Vollversion von Angry Birds ist bereits vorinstalliert – für viele Stunden Spass. Und im Ovi Store gibt es viele weitere Apps und Spiele.
";2;False;0;;;Nokia N9 Smartphone blau;nokia-n9-smartphone-blau;True;True;P-0008;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;569.0000;569.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40602,8930439815;74;17;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000280-nokia-n9-smartphone-blau.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000281-nokia-n9-smartphone-blau.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000282-nokia-n9-smartphone-blau.jpg;1;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Apple iPod Nano 8 GB verschiedene Farben;Apple iPod Nano 8 GB;"
Apple iPod Nano 8 GB
 
 
Neues gebogenes Design, der dünnste iPod, den es je gab mit neuen Farben zu Auswahl
Die Bedieung optimiert: ein einziges Handschütteln und ein anderes Lied wird gespielt
Die neue Funktion ""Genius"" findet die Songs in Ihrer Mediathek, die besonders gut zusammenpassen, und erstellt daraus eine Genius Wiedergabeliste.
Viele Abspielformate: z.B. MP3, AAC, Apple Lossless, AIFF, WAV, H.264, MPEG-4
Lieferumfang: iPod Nano, Ohrhörer, USB 2.0 Kabel, Dock-Adapter, Dokumentation
 
Neues gebogenes Design, der dünnste iPod, den es je gab mit neuen Farben zu Auswahl
Die Bedieung optimiert: ein einziges Handschütteln und ein anderes Lied wird gespielt
Die neue Funktion ""Genius"" findet die Songs in Ihrer Mediathek, die besonders gut zusammenpassen, und erstellt daraus eine Genius Wiedergabeliste.
Viele Abspielformate: z.B. MP3, AAC, Apple Lossless, AIFF, WAV, H.264, MPEG-4
Lieferumfang: iPod Nano, Ohrhörer, USB 2.0 Kabel, Dock-Adapter, Dokumentation
 
Ein musikalisches Genie
Stell Dir vor, Du hörst einen Song. Toll wären jetzt andere Titel, die gut dazu passen. Was machst du? Ganz einfach: Du verwendest die neue Funktion ""Genius"". Diese findet die Songs in Deiner Mediathek, die gut zusammenpassen. Du erhältst eine Genius Wiedergabeliste, zusammengestellt von Deinem persönlichen, superintelligenten DJ.  
Musik schneller finden
Auch einen Song, den Du hören willst, findest Du jetzt viel einfacher. Du kannst Deine Alben mit Cover Flow anzeigen oder hältst einfach die mittlere Taste gedrückt und blätterst in Deinen Alben oder Interpreten. Den gewünschten Song gefunden? Einmal auf die mittlere Taste gedrückt, und schon hast Du ihn zur aktuellen Wiedergabeliste hinzugefügt. 
 
Aufdrehen und rumdrehen
Neige Deinen iPod nano in die Waagerechte, und schon kannst Du hören, sehen oder spielen wie nie zuvor. Deine Alben kannst Du mit Cover Flow durchblättern und siehst so viel mehr Alben oder Interpreten gleichzeitig auf dem Display.
 
Shake it, Baby!
Manchmal hat man einfach Lust auf eine kleine Überraschung. Darum kannst Du jetzt komplett dem Zufall überlassen, welches Lied Du als Nächstes hörst. Einfach den iPod nano kurz schütteln – und er springt zu irgendeinem anderen Song aus Deiner Musik-Bibliothek. Lass dich überraschen, was er Dir als Nächstes präsentiert.   
Spiel ab!
Jetzt kannst Du Dir mit Spielen die Zeit vertreiben, die ganz speziell auf den iPod nano und den Beschleunigungssensor zugeschnitten sind. Sie reagieren auf Deine Bewegungen und wirken dadurch so überzeugend, dass sie fast schon süchtig machen können. In jedem Fall wirst Du begeistert sein. Bereits vorinstalliert ist Maze, wo Du Dich durch Neigen, Kippen und allerlei andere Bewegungen durch riesige Labyrinthe manövrieren musst. Im iTunes Store stehen natürlich noch viele weitere Spiele zur Auswahl.
 
Sogar Deine Fotos rocken
Jetzt kannst Du gleich hunderte von Fotos aus der Tasche zaubern und überall vorführen. Senkrecht gehalten zeigt der iPod nano Deine Fotos im Hochformat an, wenn Du ihn um 90 Grad drehst, wechseln auch die Fotos ins Querformat. Die Fotos wirken in ihrem richtigen Größen- und Seitenverhältnis auf dem brillanten Display mit 320 x 240 Pixeln einfach hervorragend. 
Der größte kleine Bildschirm der Welt
Filme, Fernsehsendungen und Videos auf dem iPod nano anzusehen, ist das pure Vergnügen. Die hochauflösende Anzeige wirkt auf dem kristallklaren 2"" Breitbild-Display besonders brillant und lebendig. So hast Du mit dem iPod nano Dein eigenes Kino im Taschenformat immer dabei.  
 
Produktbeschreibungen
Flach, flacher, am flachsten mit nur 6,2mm bringt der iPod nano, in leuchtenden Farben, neuen Schwung ins Leben.
Mit brilianterem Display, höherer Speicherkapazität und noch längerer Batterielaufzeit schütteln Sie sich einfach durch Ihre Mediathek.
Leistungsmerkmale
- Verschieden Menüs: Musik, Fernsehsendungen, Videos, Hörbücher, Podcasts, Diashows, Spiele
- Geschwungenen Aluminium-Design mit gewölbtem Glas
- HxBxT: 90,7 x 38,7 x 6,2 mm
- Gewicht: 36,8 g
Lieferumfang
- iPod nano
- Ohrhörer
- USB 2.0-Kabel
- Dock-Adapter
- Dokumentation
Display
- 2- Farb-LCD mit LED-Hintergrundbeleuchtung
- 320 x 240 Pixel
Kapazität
- 8 GB Flash-Laufwerk1 für bis zu 2.000 Songs, 7.000 Fotos, 8 Std. Videomaterial
Batterie
- Integrierte, wiederaufladbare Lithium-Ionen-Batterie
- Musikwiedergabe: bis zu 24 Stunden bei voller Ladung
- Videowiedergabe: bis zu 4 Stunden bei voller Ladung
Audio
- Unterbrechungsfreie Wiedergabe
- Frequenzbereich: 20 Hz bis 20.000 Hz
- Unterstützte Audioformate: AAC, Protected AAC, MP3, MP3 VBR, Audible, Apple Lossless, AIFF und WAV
Systemvoraussetzungen
- USB 2.0-Anschluss
- mind. Mac OS X 10.4.11 bzw. mind. Windows Vista oder Windows XP Home oder Professional
- mind. iTunes 8  

 
 
 
";2;False;0;;;Apple iPod Nano 8 GB;apple-ipod-nano-8-gb-verschiedene-farben;True;True;P-1371;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;139.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40218,6740856481;47;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000075-apple-ipod-nano-8-gb-verschiedene-farben.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000076-apple-ipod-nano-8-gb-verschiedene-farben.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000077-apple-ipod-nano-8-gb-verschiedene-farben.jpg;1;;False;;;;;False;False;False;;;;;False;;;;;; +5;210;True;_SmartStore.biz 6;Das Shopping System;"
SHOP
Mit neuesten Technologien topmoderne Ergebnisse erzielen
Durch konsequente Verwendung von HTML5, CSS3, jQuery und jQuery UI erzeugt SmartStore.biz 6 schnelle und übersichtliche Seiten. Erst kürzlich hat auch YouTube sein Portal mit diesen Technologien neu aufgestellt. Das jQuery Framework bietet komfortable Funktionen zur Manipulation von Webseiten. jQuery UI ist eine Erweiterung von jQuery und bietet Lösungen zur Gestaltung und Funktionalität der Benutzeroberfläche an.
Zusammen mit HTML5 und CSS können mit diesen Technologien komplexe Seiten hochperformant erstellt werden. Komponenten aus der jQuery UI-Bibliothek passen sich automatisch SmartStore-Theme Designs an. So können Sie selbst Komponenten und Effekte aus jQuery UI einbinden.
Facebook, Google & Co
Soziale Interaktion und Zusammenarbeit belebt den Shop und bindet Besucher. SmartStore.biz 6 bietet Möglichkeiten für die Verwendung von allen wichtigen Plattformen.
Kunden können mit Google+ und Facebook Like Ihren Shop weiterempfehlen oder über Facebook Kommentare ein Kommentar zu einem Ihrer Angebote verfassen, welcher dann auch auf der Facebook-Seite des Kunden erscheint.
Megamenü Navigation
Mehrspaltige Menüs werden immer beliebter. Die Megamenü Navigation bietet gegenüber der einfachen Dropdown Navigation größere Navigationsflächen und die Darstellung von mehreren Navigationsebenen auf einer Ebene.
Shrinkmenü
Klein aber fein. Navigationsleisten mit sehr vielen Einträgen werden oft unzureichend gut dargestellt. Meist werden Einträge abgeschnitten oder alle Einträge werden angezeigt und das Layout passt nicht mehr.
Die Funktion „Shrinkmenu“ passt die Navigation so an, dass der Platz für die Navigation optimal genutzt wird.
Produktliste
Eine Produkliste führt sämtliche Produkte eines Shops auf. Die neue Produktliste in SmartStore.biz 6 stellt Produkte wahlweise in einer mehrspaltigen Galerieansicht und in einer Listenansicht dar.
Produktdetail
Das neue Produktdetail-Modul zeigt jetzt alle zum Produkt zugehörigen Bilder in einer Galerie dar. Eine Zoom-Ansicht, in der die Bilder-Galerie in Vollbild angezeigt wird und eine Vollbild-Ansicht, in der jeweils ein Bild in einer LightBox angezeigt, erlauben Ihnen eine detaillierte und schöne Produktpräsentation. In der Vollbild-Ansicht kann zudem, ohne diese Ansicht zu verlassen zu anderen Bildern navigiert werden.
Durch die Verwendung des Tab-Moduls können Daten wie Produktbeschreibung aber auch andere Module übersichtlich dargestellt werden.
Docked Minibasket
Der neue interaktive Mini-Warenkorb dockt sich stets griffbereit in die Fußzeile des Shops an. Der Shop-Kunde kann nicht nur per Knopfdruck, sondern auch per Drag & Drop seine Waren in den Warenkorb legen.
Die detaillierte Ansicht des Warenkorbs verschafft dem Käufer stets einen klaren Überblick über seine Einkaufsliste. Derartige Design Highlights  erzeugen beim Käufer Sympathiepunkte, die sich in den meisten Fällen verkaufsfördernd auswirken.
Tabs
Das neue Tab-Modul stellt beliebige Module in Tabs dar und ermöglicht somit eine übersichtliche Darstellung von vielen Inhalten. Inhalte können so platzsparend und übersichtlich bei minimalem Platzverbrauch angezeigt werden. Überlange Seiten und langes scrollen gehören damit zur Vergangenheit.
  
Splitter
Der neue Splitter ermöglicht es, beliebig viele Module horizontal anzuordnen. Inhalten werden so platzsparend und ansprechend dargestellt.
Content-Slider
Der Content-Slider macht aus beliebigem Inhalt auf der Seite eine Dia-Show.
Stellen Sie Top-Produkte, Sonderangebote und News eindrucksvoll mit einem Conten-Slider dar. Viele hübsche und effektvolle Übergangseffekte, Auto-Slide-Modus und die Paginierung machen den Content-Slider zu einem Hingucker in Ihrem Shop. 
THEMING & DESIGN
Neue Themes
Smartstore.biz 6 enthält zwei von Grund auf neu entwickelte Themes. Ein modernes und ansprechendes Shop-Design ist somit "out-of-the-box" garantiert!
60 neue Banner-Grafiken
60 neue Banner-Grafiken aus unterschiedlichen Themenbereichen bilden die Grundlage für schicke und harmonische Banner. Mit den neuen Editierfunktionen lassen sich so hervorragende Banner mühelos mit ein paar Klicks erstellen.
Seiten-Layout
Das neue Seitenlayout basiert auf dem 960 Grid System.
Per Knopfdruck kann das Layout eines Themes verändert werden. Layout-Typen wie Feste Breite, Hybrid und Dynamisch können sofort auf jedes Theme angewendet werden.
Darüber hinaus können Außen- und Innenabstände, die Ausrichtung und die Breite der Seite einfach eingestellt werden.
HTML Container
HTML Container sind „Behälter“ für andere HTML-Elemente und dienen zur optischen Ausgestaltung. Container schaffen Übersicht und setzen Akzente.
SmartStore.biz 6 enthält eine Container-Bibliothek mit mehr als 60 modern gestalteten Containern, die sich beliebig mit jedem Theme kombinieren lassen.
Banner-Editor
Der neue Banner-Editor bietet jetzt Ausblendeffekte für Ihren Banner nach allen Seiten und intelligente Spiegelungsfunktionen. Banner können nach allen Seiten mit eleganten Ausblendeffekten versehen werden und erzielen. Mit den neuen Editierfunktionen lassen sich so hervorragende Banner mühelos mit ein paar Klicks erstellen.
WEITERE HIGHLIGHTS
User Interface
Innerhalb von SmartStore.biz 6 wurden die Funktionen in vielen Bereichen verbessert.
Die Benutzeroberfläche wurde auf den neusten Stand gebracht.
Alle wichtigen Menü-Einträge und Funktionen sind nun über ein anpassbares, Office 2010 ähnliches Ribbon erreichbar.
Page-Designer
Der Page-Designer wurde grundlegend Überarbeitet. Zur Übersichtlichkeit lassen sich nun Module auf- und zuklappen. Die Bedienung per Drag & Drop wurde intuitiver gestaltet.
Multipanel Module
Multipanel Module erzeugen aus anderen Modulen neue Darstellungen. So können z.B. aus vielen Bildern Galerien erzeugt werden oder eine Sammlung von Bildern, Buttons und Eingabefeldern kann in einem Tab dargestellt werden.
SmartStore.biz 6 beinhaltet die Multipanel Module Tab, Splitter und Content-Slider.
Ereigniskonsole
Die Ereigniskonsole zeigt Fehlermeldungen und Ereignisse beim Testen und Erstellen an.
Mit ihr lassen sich leicht Fehler in Skripten, Modulen und Plug-Ins finden. Fehler werden mit einer Beschreibung, dem Zeitpunkt des Auftritts, dem Fehler-Typ und dem Ursprung der Meldung angezeigt.
Designer und Entwickler bekommen so direkt ein Feedback über Fehler. Über Aufrufe in eigenen Anwendungen können Entwickler Zeitmessungen vornehmen oder beliebige Nachrichten in der Ereigniskonsole anzeigen
Payment-Schnittstellen
masterpayment Zahlungsschnittstelle
MASTERPAYMENT bietet das Rundum-Sorglos-Paket wie Rechnungskauf, Kreditkarte, Ratenzahlung, Sofortüberweisung jetzt für SmartStore-Händler an.
Wer in seinem SmartStore-Shop MASTERPAYMENT bis zum 31.12.2011 aktiviert, spart sich sämtliche Grundgebühren und Set-Up-Gebühren für alle Zahlarten!
Klarna Zahlungsschnittstelle
Mit Klarna Rechnung und Ratenkauf anbieten!
Klarna ist Europas führender Anbieter von rechnungsbasierten Zahlungs- und Finanzierungslösungen im Internethandel. Rechnung und Ratenkauf mit Klarna bieten Onlineshoppern entscheidende Vorteile.
BillSafe Zahlunsschnittstelle
Mit BillSAFE bieten Sie Ihren Kunden die beliebteste Zahlart in Deutschland – den Kauf auf Rechnung! Dadurch steigern Sie Ihren Umsatz, gewinnen
neue Käufergruppen und erhöhen den Anteil an Bestandskunden. Das alles geht mit
BillSAFE völlig ohne Ausfallrisiko..
";2;True;0;;;SmartStore.Biz 6;_smartstorebiz-6;True;True;P-6000;;MYEAN-65487;False;0;False;;False;False;0;True;0;1;False;;False;;False;100;0;10;True;False;0,0000;False;False;1;2;10000;True;True;0;0;0;0;False;1;10000;;False;False;False;False;190.0000;0.0000;0.0000;166.0000;42248,5157986111;42250,9999884259;False;100.0000;200.0000;0.0000;0.0000;0.0000;0.0000;40218,6501736111;"29;78;81;2095";42;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000070-_smartstorebiz-6.png;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000071-_smartstorebiz-6.png;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000072-_smartstorebiz-6.png;3;1;True;kg;2.0000;1;;False;False;False;;;;;False;;Toll Software DE;"

Langbeschreibung

";SmartStore Biz EN;Nice software;"

Long descriiption

" +5;0;True;Sandisk Sansa Clip 2 GB rot;Sandisk Sansa Clip 2 GB mit integriertem FM-Tuner rot;"

Sandisk Sansa Clip 2 GB mit integriertem FM-Tuner rot

digitaler SanDisk Player für MP3, WMA, Secure WMA und FM Radio
kleines, kompaktes Design, kaum größer als eine Streichholzschachtel
FM-Radio mit 40 Stationsspeicherplätzen
Diktiergerät-Funktion über integriertes Mikrofon
4-zeiliges OLED-Display
 
Sortierung der Titel nach versch. Kriterien möglich, wie z.B. Künstler, Album, Genre, u.a.
bis zu 15-h-Wiedergabe mittels internem, wiederaufladbaren Akku
inkl. abnehmbarem Trageclip, Ohrhörer, USB 2.0 Kabel, Installations-CD mit Bedienungsanleitung
unterstützt Win 2000 / XP / Vista
 
Lieferumfang:
Player inkl. abnehmbarem Trageclip, Ohrhörer, USB 2.0 Kabel, Installations-CD mit Bedienungsanleitung
";2;False;0;;;"Sandisk Sansa Clip 2 GB mit integriertem FM-Tuner ";sandisk-sansa-clip-2-gb-rot;True;True;P-1620;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;42.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40206,8077430556;52;8;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000571-sandisk-sansa-clip-2-gb-rot.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Sandisk Sansa Fuze 8 GB silber;"Sandisk Sansa Fuze MP3-/Video-Player 8 GB mit Radio silber ";"

Sandisk Sansa Fuze MP3-/Video-Player 8 GB mit Radio silber

 
 
Mit der verfügbaren Akkuleistung können Sie 24 Stunden lang Musik hören, Bilder anschauen oder spielen.
Der neue Sansa Fuze von SanDisk ist der ideale tragbare Musikplayer für Sie.
Er steht mit einer Speicherkapazität 4 GB in schwarz,rot,pink zur Verfügung.
Sehen Sie sich Ihre Lieblingsvideoclips auf dem 1,9""-Farbdisplay des Sansa Fuze an.
Lauschen Sie dem FM-Radio mit 40 voreingestellten Sendern oder probieren Sie den integrierten Sprachrekorder aus. Mit einer unglaublich starken Akkuleistung in einem 0,3"" schmalen Gerät setzt der Sansa Fuze Zeichen.
";2;False;0;;;Sandisk Sansa Fuze MP3-/Video-Player 4 GB mit Radio;sandisk-sansa-fuze-8-gb-silber;True;True;P-1610;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;89.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40206,8019444444;52;8;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000570-sandisk-sansa-fuze-8-gb-silber.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Asus Eee PC 1001HA 10,1 Zoll Netbook;Asus Eee PC 1001HA 10,1 Zoll Netbook;"
Eee PC™ 1001HA: Klasse Leistung zu unschlagbarem Preis
 
Der Eee PC™ 1001HA unterscheidet sich von seinen großen Brüdern durch Prozessor und Akkukapazität. Ausgestattet mit einem Intel® Atom™ N270 Prozessor, einem 3 Zellen Akku für bis zu 4 Stunden Laufzeit, WLAN 802.11n Standard sowie weiteren Top Merkmalen, überzeugt der Eee PC™ 1001HA zu einem wirklich unschlagbaren Preis.
 
Eee PC™ 1001HA: Funktionalität meets Design
 
Mit dem kompakten Eee PC™ 1001HA trägt ASUS seinem Anspruch, in den Produkten höchste Funktionalität mit formvollendetem Design zu verbinden, ein weiteres Mal Rechnung. So besticht der neue Eee PC™ durch sein elegantes und gleichzeitig unempfindliches Gehäuse, das mit klaren Linien und nach unten schmaler zulaufenden Kanten dem schlanken Design einer Muschel nachempfunden ist. Aber auch das Innenleben der Kleinen kommt ganz groß raus. Als gewohnt kontaktfreudig erweisen sich die Neulinge dank VGA Port für den Anschluss eines Monitors sowie drei USB 2.0 Schnittstellen, um Maus, Tastatur oder Digicam anzuschließen. Wer Bilder direkt von der SD oder MMC Speicherkarte auf den Eee PC™ übertragen möchte, nutzt den integrierten Kartenleser. Für das Speichern der Fotos stehen bei beiden Modellen eine 160 GB S-ATA Festplatte zur Verfügung.. Das Modell basiert auf Microsoft® Windows® XP Home und ist – wie alle Eee Familienmitglieder – ausgesprochen einfach zu bedienen. Das 10 Zoll WSVGA Display mit stromsparender LED-Hintergrundbeleuchtung sowie die große Tastatur, die zu 92% einer Standard Notebooktastatur entspricht, gewähren zusätzlichen Komfort. Für Chats oder Videokonferenzen hat ASUS die Minis zudem mit einer 0.3 Megapixel Web-/Videokamera sowie einem Mikrofon ausgestattet.
 
 
";2;False;0;;;Asus Eee PC 1001HA 10,1 Zoll;asus-eee-pc-1001ha-101-zoll-netbook;True;True;P-0890;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;243.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40205,9519907407;6;37;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000563-asus-eee-pc-1001ha-101-zoll-netbook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000564-asus-eee-pc-1001ha-101-zoll-netbook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000565-asus-eee-pc-1001ha-101-zoll-netbook.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Canon PGI 520BK Tintenpatrone schwarz;Canon PGI 520BK Tintenpatrone schwarz;"
Canon PGI 520BK ,Tintenpatrone, schwarz, 19ml
 
 
 
kompatibel  PIXMA iP3600/iP4600/IP4700 und MP540/620/630/640

 
 
";2;False;0;;;"Canon CLI-521, Tintenpatrone, cyan, 9ml, für PIXMA iP3600/iP4600/IP4700 und MP540/620/630/980 - ""R"" ";canon-pgi-520bk-tintenpatrone-schwarz;True;True;P-2280;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;-1,2000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;11.9900;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40205,7303009259;23;25;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000562-canon-pgi-520bk-tintenpatrone-schwarz.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Canon CLI-521 Tintenpatrone schwarz;Canon CLI-521 Tintenpatrone;"
Canon CLI-521BK,Tintenpatrone, schwarz, 9ml
 
 
 
kompatibel  PIXMA iP3600/iP4600/IP4700 und MP540/620/630/640

 
 
";2;False;0;;;"Canon CLI-521, Tintenpatrone, cyan, 9ml, für PIXMA iP3600/iP4600/IP4700 und MP540/620/630/980 - ""R"" ";canon-cli-521-tintenpatrone-schwarz;True;True;P-2270;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;-1,2000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;11.9900;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40205,7265509259;23;25;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000555-canon-cli-521-tintenpatrone-schwarz.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Canon CLI-521 Tintenpatrone magenta;Canon CLI-521 Tintenpatrone;"
Canon CLI-521M,Tintenpatrone, magenta, 9ml
 
 
 
kompatibel  PIXMA iP3600/iP4600/IP4700 und MP540/620/630/640

 
 
";2;False;0;;;"Canon CLI-521, Tintenpatrone, cyan, 9ml, für PIXMA iP3600/iP4600/IP4700 und MP540/620/630/980 - ""R"" ";canon-cli-521-tintenpatrone-magenta;True;True;P-2260;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;-1,2000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;11.9900;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40205,7246643519;"23;2095";25;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000554-canon-cli-521-tintenpatrone-magenta.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Canon CLI-521 Tintenpatrone cyan;Canon CLI-521 Tintenpatrone;"
Canon CLI 521C,Tintenpatrone, cyan, 9ml
 
 
 
kompatibel  PIXMA iP3600/iP4600/IP4700 und MP540/620/630/640

 
 

 
 
";2;False;0;;;"Canon CLI-521, Tintenpatrone, cyan, 9ml, für PIXMA iP3600/iP4600/IP4700 und MP540/620/630/980 - ""R"" ";canon-cli-521-tintenpatrone-cyan;True;True;P-2250;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;-1,2000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;11.9900;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40205,7210416667;23;25;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000553-canon-cli-521-tintenpatrone-cyan.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Canon CLI-521 Tintenpatrone gelb;Canon CLI-521 Tintenpatrone;"
Canon CLI-521Y,Tintenpatrone, gelb, 9ml
 
 
 
kompatibel  PIXMA iP3600/iP4600/IP4700 und MP540/620/630/640

 
 
";2;False;0;;;"Canon CLI-521, Tintenpatrone, cyan, 9ml, für PIXMA iP3600/iP4600/IP4700 und MP540/620/630/980 - ""R"" ";canon-cli-521-tintenpatrone-gelb;True;True;P-2240;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;-1,2000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;11.9900;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40205,6889814815;23;25;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000552-canon-cli-521-tintenpatrone-gelb.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Philips DC 200 iPod Soundsytem ";"Philips DC 200 iPod Soundsytem ";"
Philips DC 200 iPod Soundsytem  - Radio, USB, Apple iPod kompatibel

Genießen Sie Ihre MP3-Lieblingsmusik auch beim Aufladen Ihres iPods! Dank der Docking-Station können Sie Ihren iPod direkt an das Docking-Entertainment-System anschließen und Ihre Lieblingsmusik in ausgezeichneter Soundqualität wiedergeben.
 
Ihr iPod wird während der Wiedergabe aufgeladen, sodass Sie Ihre Musik genießen können, ohne sich Gedanken über den Ladestand des Akkus machen zu müssen. Verwenden Sie zum Durchsuchen, Auswählen und Wiedergeben der auf dem iPod gespeicherten Musiktitel die Fernbedienung.
 
Das Docking-Entertainment-System lädt Ihren iPod automatisch auf, solange er sich in der Station befindet.
Durch den direkten USB-Anschluss können Sie einfach Musik auf einem USB-Gerät auswählen und wiedergeben.
Um Musik wiederzugeben oder Inhalte zu exportieren, stecken Sie das USB-Gerät einfach ein.
Das digitale UKW-Radio bietet Ihnen zusätzliche Musikoptionen für die Musiksammlung auf Ihrem Philips Player.
Stellen Sie einfach den gewünschten Radiosender ein, und halten Sie die Speichertaste gedrückt, um die Frequenz zu speichern.
 
Dank der voreingestellten und gespeicherten Radiosender können Sie ganz einfach Ihren Lieblingssender hören,
ohne die Frequenz jedes Mal manuell einstellen zu müssen.
 
Das Bassreflex-Lautsprechersystem sorgt bei kompakten Lautsprecher-Systemen für tiefe Bässe.
Der Unterschied zu konventionellen Lautsprecher-Systemen liegt in der Tiefbassröhre, die akustisch auf den Woofer abgestimmt ist,
 
um den Low Frequency Roll Off des Systems zu optimieren. Ergebnis sind tiefer gesteuerte Bässe und weniger Verzerrung.
 
Das Prinzip besteht darin, dass die Luftmasse in der Tiefbassröhre mitschwingt und wie ein herkömmlicher Woofer vibriert.
 
In Kombination mit der Reaktion des Woofers erweitert das System alle niederfrequenten Töne und erzeugt tiefe Bässe in einer völlig neuen Dimension.
 
Lieferumfang: 3,5 mm Stereo-Line-Eingangskabel;AC/DC-Adapter;Schnellstartanleitung;Benutzerhandbuch
";2;False;0;;;;philips-dc-200-ipod-soundsytem;True;True;P-1540;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;82.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40203,8622569444;"51;2095";6;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000544-philips-dc-200-ipod-soundsytem.jpg;;;1;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Logitech G500 Gaming Maus ";"Logitech G500 Gaming Maus ";"
 Logitech G500 Gaming Maus
 
 
 
Der spieletaugliche Laser geben Ihnen bei jeder Bewegungsgeschwindigkeit eine atemberaubende Präzision
Durch Feintuning mit bis zu 27 Gramm an zusätzlichen Gewichten bestimmen Sie exakt, wie die Maus in der Hand liegt
 
Der integrierte Speicher ermöglicht es Ihnen, die Einstellungen für Dein Lieblingsspiel zu speichern und mitzunehmen – es ist keine Software erforderlich

Das Tastenrad bietet Ihnen zwei Einstellungen – den präzisen Click-to-Click-Modus oder hyperschnelle Bildläufe
 
Lieferumfang:
Logitech G500 Gaming Maus, Anpassbares Gewichtsmagazin, Tuninggewichte und Etui, Bedienungsanleitung
";2;False;0;;;"Logitech G500 Gaming Maus ";logitech-g500-gaming-maus;True;True;P-2820;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;59.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40203,8042476852;21;11;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000543-logitech-g500-gaming-maus.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Garmin nüvi 205 Navigationssystem DACH;Garmin nüvi 205 Navigationssystem DACH;"
Garmin nüvi 205 Navigationssystem DACH
 
 
3,5 Zoll Touchscreen Display, PhotoNavigation, MicroSD-Kartenslot und ecoRoute
 
 
Bedienerfreundliches Einsteigernavigationsgerät mit elegantem, ultra-schlankem Design
und brillantem 3,5 Zoll (8,9cm Bilddiagonale) Touchscreen Display
Detailkarten für Deutschland, Österreich, Schweiz + CZ intern vorinstalliert
ecoRoute: reduziert den Kraftstoffverbrauch, CO2-Emissionen
und schont die Umwelt, spart bares Geld und füllt die Reisekasse auf.
PhotoNavigation mit Garmin Connect: Sie können Sehenswürdigkeiten und Bilder herunterladen und als Ziel auswählen
Lieferumfang: Garmin nüvi 205 mit Kartenmaterial DACH,
Saugnapfhalterung für die Windschutzscheibe, Armaturenhalterung, Schnellstartanleitung, KFZ-Anschlusskabel
";2;False;0;;;Garmin nüvi 205 Navigationssystem DACH;garmin-nuevi-205-navigationssystem-dach;True;True;P-2110;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;139.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40200,8638078704;67;44;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000542-garmin-nuvi-205-navigationssystem-dach.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"AVM FRITZ!Fon C3 VoIP Dect-Telefon ";"AVM FRITZ!Fon C3 VoIP Dect-Telefon ";"
FRITZ!Fon C3: HD-Telefonie und komfortable Internetdienste mit DECT.
Telefonieren Sie mit dem Schnurlostelefon FRITZ!Fon C3 in bestechender Qualität über das Internet und nutzen Sie komfortable Webdienste. Als intelligentes Telefon der neuesten DECT-Generation vereint das FRITZ!Fon den Komfort der schnurlosen Telefonie mit den Qualitäts- und Leistungsmerkmalen der Internettelefonie (VoIP) in einem Gerät.
 
Bei der Internettelefonie mit einem FRITZ!Fon wird durch HD-Telefonie (High Definition) ein brillantes, natürliches Klanggefühl erreicht. Sprache lässt sich mit dem FRITZ!Fon in ihrem gesamten Frequenzspektrum wiedergeben, was die Klangqualität von Festnetzverbindungen deutlich übertrifft.
 
FRITZ!Fon unterstützt die übertragung großer Bandbreiten. Dies ermöglicht neben HD-Telefonie auch die Nutzung komfortabler Internetdienste wie den Empfang von E-Mails, Podcasts, RSS-Feeds und Internetradio.
 
Die Steuerung von FRITZ!Box-Anwendungen am Handgerät bietet viel zusätzlichen Komfort. Und durch DECT-Eco wird Funkabstrahlung bei Nichtnutzung der Telefone verhindert.
 
Die FRITZ!Box-Modelle FRITZ!Box Fon WLAN 7390, 7320, 7270, 7240 sowie FRITZ!Box 6360 Cable stellen mit der integrierten DECT-Basisstation, mehreren Anrufbeantwortern und Telefonbüchern für bis zu 300 Einträge den idealen Partner für das FRITZ!Fon dar. Mit der umfangreichen Prozessor- und Speicherausstattung ist auch der Grundstein für neue Anwendungen gelegt. Denn das FRITZ!Fon ist lernfähig:
 
Als eines der ersten intelligenten Schnurlostelefone wird es auch künftig per Firmware-Updates aktualisiert und um neue Funktionen erweitert werden können.
 
Umfangreicher Komfort
Das FRITZ!Fon C3 ist mit zahlreichen Komfortfunktionen ausgestattet. Dazu zählen Lauthören und Freisprechen in HD-Qualität sowie ISDN-Leistungsmerkmale wie Namensanzeige bei bekannten Rufnummern, Halten, Makeln, Anklopfen, Rufumleitung oder Dreierkonferenz. Die Internettelefonie in HD-Qualität lässt sich so in ihrem vollen Umfang und Komfort nutzen, ohne dass der Computer eingeschaltet sein muss.
 
FRITZ!Fon informiert zudem aktiv über unbeantwortete Anrufe, Nachrichten auf dem Anrufbeantworter und zeigt eingegangene E-Mails an. An der DECT-Basisstation der FRITZ!Box Fon WLAN 7390, 7320, 7270, 7240 oder FRITZ!Box 6360 Cable lassen sich bis zu 6 FRITZ!Fon-Handgeräte oder andere DECT-Telefone anmelden. Die Erstinstallation und individuelle Einstellungen erfolgen dabei bequem über einfache Assistenten.
 
FRITZ!Box als idealer Partner
Das FRITZ!Fon C3 kann als Mobilteil an jeder DECT-Basisstation eingesetzt werden. Im Zusammenspiel mit der FRITZ!Box Fon WLAN 7390, 7320, 7270, 7240 oder FRITZ!Box 6360 Cable kann jedoch das volle Spektrum der Möglichkeiten beim Telefonieren und Surfen über das Internet ausgenutzt werden.
 
Die FRITZ!Box Fon WLAN 7390 zum Beispiel vereint eine bisher nicht erreichte Vielfalt in einem Gerät: VDSL- und ADSL-Unterstützung, DECT-Basisstation fürs schnurlose Telefonieren sowie WLAN N für die optimale Datenübertragung. über den Mediaserver sind gespeicherte Filme, Musik und Bilder auch bei ausgeschaltetem Computer im gesamten Netzwerk verfügbar. Darüber hinaus kann der Online-Speicher wie eine lokale Festplatte genutzt werden. So wird die FRITZ!Box Fon WLAN 7390 zur idealen Plattform für vernetzte Anwendungen wie IPTV, Video on Demand oder Mediastreaming.
 
Bedienung
- Schnelle Anmeldung: Einschalten, Suchtaste der FRITZ!Box drücken, fertig.
 
- Einfache Bedienung über intuitives Menü.
 
- Telefonbuch komfortabel über FRITZ!Box-Oberfläche einrichten und anzeigen.
 
- In FRITZ!Box integrierte Anrufbeantworter einfach am C3 einrichten und abhören.
 
- Blinkendes Nachrichtensymbol signalisiert eingegangene Anrufe, neue Nachrichten auf dem Anrufbeantworter und neue E-Mails.
 

Telefonieren Sie mit dem Schnurlostelefon C3 in bestechender Qualität über das Internet und nutzen Sie komfortable Webdienste.
 
Highlights
- DECT-Telefon für Internet- und Festnetztelefonie, ideal geeignet für die FRITZ!Box Modelle 7270, 7240, 7390 und 6360 Cable
- Farbdisplay und beleuchtete Tastatur
- Telefonbücher für bis zu 300 Einträge, Online-Telefonbuch verfügbar
- Mehrere Anrufbeantworter mit Menüsteuerung und Fernabfrage
- Full-Duplex-Freisprechen
- Unterstützt HD-Telefonie nach CAT-iq
- Per Software-Update einfach um neue Funktionen erweiterbar
 
Eigenschaften DECT-Telefon
- Mobilteilbreite: 49 mm
- Mobilteilhöhe: 138 mm
- Mobilteiltiefe: 26 mm
- Gewicht Mobilteil inkl. Akku: 133 g
- Feldstärkeanzeige
- Freisprechfunktion
- CAT-iq Standard
- Strahlungsarm
- GAP-fähig
- Reichweite im Freien bis zu 300 m
- Reichweite in Gebäuden bis zu 40 m
 
Telefoneigenschaften
- Anruferanzeige (CLIP)
- Picture-CLIP
- Anruferliste
- Anzeige Datum/Uhrzeit
- Anzeige Gesprächsdauer
- Polyphone Klingeltöne: ja
- Hörerlautstärke einstellbar
- Stummschaltung möglich
- Bis zu 300 Telefonbucheinträge
- Wecker
- Telefontyp: Schnurlostelefon
 
Grundeigenschaften
- Farbe: Silber
 
Lieferumfang
- FRITZ!Fon C3
- AAA-Akkupack
- Ladestation
- Netzteil zum Anschluss an das 230-Volt-Stromnetz
- Gedrucktes deutschsprachiges Handbuch
 

Kompatibel zu:
FRITZ!Box Fon WLAN 7270, FRITZ!Box Fon WLAN 7240, FRITZ!Box Fon WLAN 7320, FRITZ!Box Fon WLAN 7390, FRITZ!Box 6360 Cable
";2;False;0;;;"AVM FRITZ!Fon C3 VoIP Dect-Telefon ";avm-fritzfon-c3-voip-dect-telefon;True;True;P-2750;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;69.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40200,5014467593;20;34;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000537-avm-fritzfon-c3-voip-dect-telefon.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000538-avm-fritzfon-c3-voip-dect-telefon.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000539-avm-fritzfon-c3-voip-dect-telefon.jpg;3;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Canon PIXMA MP560 Multifunktionsgerät 3 in 1;Canon PIXMA MP560 Multifunktionsgerät 3 in 1;"Canon PIXMA MP560 Multifunktionsgerät
 
3 in 1, Drucken, Kopieren, Scannen

Multifunktionssystem: Fotodrucker, Farbscanner und Farbkopierer
Druckgeschwindigkeit: ca. 9,2 (SW) bzw. 6,0 (Farbe) ISO-Seiten/Min; einzelne Tintentanks
ca. 39 Sek. für den druck eines 10 x 15 cm Randlosprint in Laborqualität
Benutzerfreundliches und intuitives Interface; 5 cm Display und Easy-Scroll-Bedienrad
Lieferumfang: PIXMA MP560, Netzkabel, Druckkopf, Tintentanks, Kurzanleitung,CD mit Installations-Software und Benutzerhandbuch, ";2;False;0;;;"Canon PIXMA MP640 ";canon-pixma-mp560-multifunktionsgeraet-3-in-1;True;True;P-2230;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;139.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40194,5747453704;22;25;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000460-canon-pixma-mp560-multifunktionsgerat-3-in-1.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000461-canon-pixma-mp560-multifunktionsgerat-3-in-1.jpg;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Panasonic Lumix DMC-FS7 Digitalkamera schwarz;"Panasonic Lumix DMC-FS7 Digitalkamera schwarz ";"
Panasonic Lumix DMC-FS7 Digitalkamera schwarz

10 Megapixel, 4-fach opt. Zoom, 6,9 cm Display, Bildstabilisator
 
Im Intelligenten Automatik (iA)-Modus werden die 5 wichtigsten Motivprogramme automatisch optimal auf die jeweilige Szene eingestellt.
Neben der Motiverkennung kombiniert iA weitere wichtige Funktionen, wie den optischen Bildstabilisator OIS,
die Bewegungserkennung (Intelligente ISO-Steuerung), eine optimierte Gesichtserkennung mit digitaler Rotaugen-Korrektur. So sind scharfe, natürliche und schöne Fotos selbst für (Neu-)Einsteiger möglich.
 
Lichtstarkes F2,8 Leica DC Vario-Elmarit Objektiv
Hochauflösendes 6,9 cm LC-Display [230.000 Pixel]
4x optischer Zoom [KB: 33-132 mm]
Intelligente Automatik [u.a. Gesichtserkennung]
 
Lieferumfang:
Digitalkamera, Lithium Ionen Akku, Ladegerät, USB-Kabel, Trageriemen, Audio / Video-Kabel, CD-ROM, Sotware
";2;False;0;;;"Panasonic Lumix DMC-FS6 ";panasonic-lumix-dmc-fs7-digitalkamera-schwarz;True;True;P-1780;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;169.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40189,6771412037;58;12;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000453-panasonic-lumix-dmc-fs7-digitalkamera-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000454-panasonic-lumix-dmc-fs7-digitalkamera-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000455-panasonic-lumix-dmc-fs7-digitalkamera-schwarz.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Casio EX-H10 SR Digitalkamera silber;Casio EX-H10 SR Digitalkamera silber;"
Casio EX-H10 SR Digitalkamera silber
 
12 Megapixel, 10-fach opt. Zoom, 7,6 cm  Display, Bildstabilisator
 
Die Kombination aus einem energiesparenden Prozessor und einem extrem leistungsstarken Lithium-Ionen-Akku sorgt dafür, dass der EXILIM EX-H10 auch an langen, erlebnisreichen Tagen nicht der Strom ausgeht und sie mit einer Akkuladung bis zu 1000 Fotos machen kann.
 
12,1 Megapixel CCD-Chip
10fach optischer Zoom mit mechanischem Bildstabilisator, 4fach digitaler Zoom, 24 mm Weitwinkel Objektiv
7,6 cm (3,0 Zoll) TFT-Farbdisplay (Super Clear LCD)
Bis zu 1000 Fotos mit einer Akkuladung
 
Lieferumfang:
Digitalkamera EX-H10 silber, wiederaufladbarer Lithium-Ionen-Akku , Ladegerät, AC-Anschlusskabel, USB-Kabel, AV-Kabel, Trageriemen, CD-ROM
";2;False;0;;;"Casio EX-H10 SR Digitalkamera ";casio-ex-h10-sr-digitalkamera-silber;True;True;P-1760;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;289.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40189,6684375;57;9;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000450-casio-ex-h10-sr-digitalkamera-silber.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000451-casio-ex-h10-sr-digitalkamera-silber.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000452-casio-ex-h10-sr-digitalkamera-silber.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;BenQ G2420HDBL 61 cm 24 Zoll TFT Monitor schwarz;BenQ G2420HDBL 61 cm (24 Zoll) Full-HD LED-Monitor (DVI, VGA, Reaktionszeit 5ms) schwarz;"
BenQ G2420HDBL - Der High-End-Entertainer!
Der G2420HDBL LED-Monitor mit seiner BenQ LED-Edge-Backlight-Technologie im 16:9 Widescreen-Format und einer Bilddiagonale von 61 cm (24 Zoll) verfügt über eine Full-HD-Auflösung (1920 x 1080p), einen dynamischen Kontrast von 5.000.000:1, eine Reaktionszeit von 5 ms sowie eine Helligkeit von 250 cd/m². Zusätzlich sorgt die BenQ Senseye®-Photo-Technologie für eine perfekte Bildqualität bei jeder Anwendung. Mit seinem schwarz glänzenden Design ergänzt dieses PC-Display elegant jedes Büro und jedes Zuhause.
 
Sparen Sie Energie - und Geld!
Aufgrund der stetig zunehmenden globalen Erderwärmung wird es immer wichtiger, CO²-Emissionen zu reduzieren. Die LED Monitore von BenQ haben einen um 36% verringerten Energieverbrauch im Vergleich zu herkömmlichen Monitoren. Im Eco-Modus sparen Sie nochmal 30% der Energie! Und schonen zusätzlich auch noch Ihren Geldbeutel!
 
BenQ Senseye® Human Vision Technology
Mit 6 proprietären Verfahren für die Kalibrierung eines perfekten Bildes.
Dank der Senseye® Technologie und der 6 verschiedenen Techniken zur Farbkalibrierung, zeigen BenQ LED Monitore echte Farben.
 
Comfortable
Die Helligkeit des Monitors lässt sich so fein einstellen, dass Sie ein perfekt ausgeleuchtetes Bild erhalten.
 
Clear
Exakte Ränder und Bilder, die scharf bis ins kleinste Detail sind.
 
Detailed
Detaillierte Bilder dank des hohen dynamischen Kontrasts von 5.000.000:1.
 
Clean
Sämtliche Darstellungen sind frei von Bildrauschen.
 
Brilliant
Klarere Bilder und leuchtend echte Farben lassen die Bilder farbenfroh erscheinen.
 
Balanced
Dank eines integrierten Algorithmus enthält die Bilddarstellung ein ausgewogenes Farbbild.
   
Herausragende LED Farbgestaltung
 
1080p Full-HD (1920x1080 High Definition)
Full-HD-Displays bieten ein breitformatiges Vollbild mit 1080p-Auflösung nach dem HD-Standard (High-Definition). So kann z. B. mit Blu-ray-Playern, Multimedia-PCs, Notebooks oder Spielekonsolen der neuesten Generation das volle Bild digital ohne Kompromisse in brillantester Bildqualität dargestellt werden. Mit dem 16:9-Wide-Format, das perfekt für die Darstellung von Full-HD-Filmen ist, wird zudem bis zu 30 % mehr Bildfläche dargestellt als beim 4:3-Format.
 
Dynamischer Kontrast von 5.000.000:1!
Der extrem hohe dynamische Kontrast von 5.000.000:1 zeigt - insbesondere in dunkleren und komplexen Bewegungsbildern, wie bei Filmen und Video-Spielen - sogar die kleinsten Details in brillanter Schärfe. Sie erhalten fantastische Bilddetails sowie ein klares Bild auch bei dunklen, komplexen und bewegten Bildern. Noch nie haben Sie ein reineres weiß oder ein tieferes schwarz gesehen!
 
16:9 Format - Die 10%, die Ihr visuelles Vergnügen vervollständigen!
Wenn ein traditioneller 16:10 Monitor 16:9 Signale in Full-HD Bilder umwandelt, geschieht dies normalerweise auf zwei Wegen. Die erste Möglichkeit wäre, die Bilder zu strecken, was zu Verzerrungen führt. Eine andere Variante wäre, das überschüssige Bild mit schwarzen Balken zu verdecken. Beide Wege, ob eine Streckung von 10 % oder eineVerdeckung von 10 % des Bildes, haben einen erheblichen Einfluss auf den Bildgenuss.
 
Die BenQ Full-HD 16:9 LED-Monitore hingegen bieten Ihnen eine Punkt-für-Punkt Full-HD Bildübermittlung, um die Probleme der 16:10 Monitore zu lösen. Nun können Sie endlich eine 100 %-ige Full-HD Performance genießen, auf die Sie gewartet haben!
 
Für eine saubere Umwelt
 
Umweltschutz durch Reduzierung des Verpackungsmaterials
Unser Beitrag zum Umweltschutz: 80% des Verpackungsmaterials besteht aus recyceltem Papier, das Verpackungsmaterial insgesamt wird stark reduziert. Dank der schlanken LED-Panels erhöht sich beim Transport der Monitore das freie Ladevolumen um 56% (im Vergleich zur letzten Modellreihe E2400HD). Wir helfen, die Wälder zu schützen und CO2-Emissionen zu reduzieren!
 
Wasserressourcen schützen
Quecksilber-freie LED-Panels reduzieren die Umweltverschmutzung auf der Erde. Da im Produktionsprozess kein Quecksilber verwendet wird und beim Recycling der Altgeräte kein Quecksilber entsorgt werden muss, halten sie die Wasserressourcen frei von giftigen Schadstoffen.
 
Abfallbelastung reduzieren
BenQ LED Monitore sind nicht beschichtet und zu 100% recycelbar. Um die Ressourcen zu schonen, besteht der Displayrahmen zu 28% aus recycelten Plastikmaterialien. Für das Bedrucken des Verpackungsmaterials verwendet BenQ Tinte aus einem natürlichen Rohstoff: der Sojabohne. Damit lässt sich der Tintenverbrauch um 70% reduzieren.
 
";2;False;0;;;BenQ G2420HDBL 61 cm 24 Zoll TFT Monitor schwarz;benq-g2420hdbl-61-cm-24-zoll-tft-monitor-schwarz;True;True;P-2510;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;149.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40187,661724537;"10;2095";;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000443-benq-g2420hdbl-61-cm-24-zoll-tft-monitor-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000444-benq-g2420hdbl-61-cm-24-zoll-tft-monitor-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000445-benq-g2420hdbl-61-cm-24-zoll-tft-monitor-schwarz.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Benq E2220HD 21,5 Zoll TFT Monitor schwarz;Benq E2220HD 21,5 Zoll TFT Monitor schwarz glänzend;"
1080p Full HD (1920x1080 High-Definition)
Im Gegensatz zu konventionellen LCD-Monitoren bieten Full-HD-Displays ein breitformatiges Vollbild mit 1080p-Auflösung nach dem HD-Standard (High-Definition). So kann z. B. mit Blu-ray-Playern, Multimedia-PCs, Notebooks oder Spielekonsolen der neuesten Generation das volle Bild digital ohne Kompromisse in brillantester Bildqualität dargestellt werden. Mit dem 16:9-Wide-Format, das perfekt für die Darstellung von Full-HD-Filmen ist, wird zudem bis zu 30 % mehr Bildfläche dargestellt als beim 4:3-Format.
 
HDMI (High-Definition Multimedia Interface)
Der HDMI-Anschluss ist eine digitale Schnittstelle, die für den Videobereich entwickelt wurde und neben dem Bild auch den Ton überträgt. HDMI ermöglicht nicht nur Datentransfers von 5 GB/s, sondern verhindert auch Wandlungsverluste und sorgt so für eine ausgezeichnete Bildqualität. Die HDMI-Schnittstelle ist der neue Standard für die digitale Signalübertragung, unter anderem für DVD-Player oder Spielkonsolen. Ab dem Standard HDMI 1.3 sind Übertragungsraten von bis zu 10 GB/s (je nach Kabelqualität und -länge) möglich. Dadurch werden die großen Datenströme ohne Kompressionen und damit ohne Bildstörungen übertragen. Dies ist für die Abbildung von Full-HD (1080p) wichtig, um einen ruckelfreien Bildfluss zu gewährleisten. Das BenQ E2220HD Display verfügt über 2 HDMI 1.3-Schnittstellen.
 
Vier USB-Schnittstellen
Das E2220HD verfügt über gleich vier USB-Schnittstellen, so dass Sie gleichzeitig Ihre Tastatur, die Maus, ein Handy und z.B. Game-Controller anschließen können!
 
Dynamischer Kontrast von 50.000:1
Mit einem dynamischen Kontrast von 50.000:1 werden Ihre Bilder lebendiger! Sie erhalten fantastische Bilddetails sowie ein klares Bild auch bei dunklen, komplexen und bewegten Bildern. Um die Funktion zu steuern, schalten Sie einfach den Q-Pilot ein.
 
Stereo-Lautsprecher
Das E2220HD verfügt über 2 1,5 Watt Stereo-Lautsprecher, die Ihnen ein perfektes Klangerlebnis liefern.
";2;False;0;;;Benq E2220HD 21,5 Zoll TFT Monitor schwarz;benq-e2220hd-215-zoll-tft-monitor-schwarz;True;True;P-2500;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;199.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40187,6466435185;10;;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000438-benq-e2220hd-215-zoll-tft-monitor-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000439-benq-e2220hd-215-zoll-tft-monitor-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000440-benq-e2220hd-215-zoll-tft-monitor-schwarz.jpg;1;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Apple iPod Touch 32 GB schwarz;Apple iPod Touch 32 GB schwarz;"
Apple iPod Touch 32 GB schwarz
 
mit integrierter WiFi Funktion
 
Ein großartiger iPod. Ein großartiger Taschencomputer. Großartiger mobiler Spielspaß. Und das Ganze in einem unglaublich schlanken, eleganten neuen Design aus Edelstahl. Filme, Videos und Fernsehsendungen auf einem 3,5"" Display ansehen!
 
Im Web surfen, mailen!
Multitouch-Oberfläche: Die revolutionäre Technologie des iPhone und die Software Version 3.1 stecken in diesem genialen iPod. Das brillante Breitformat-Display rückt Ihre Videos und Spiele ins beste Licht
 
Surfen Sie mit Safari im Web und sehen Sie YouTube Videos auf dem iPod mit integrierter Wi-Fi Funktionalität an.
Mit Ihrem iPod touch können Sie im iTunes Wi-Fi Music Store nach Songs suchen, Hörproben abspielen und Titel kaufen.  Lieferumfang: iPod touch, Ohrhörer, USB 2.0 Kabel, Dock-Adapter, Kurzanleitung
 
Der iPod touch kann alles, was du am iPod toll findest. Und noch vielmehr.
Du kannst Filme, Videos und Fernsehsendungen auf einem 3,5"" Display ansehen. Mit der revolutionären Multi-Touch-Technologie kannst du dein Musikarchiv mit Cover Flow durchblättern. Und wenn dir nach mehr ist, tipp einfach auf iTunes, um durch das Angebot zu stöbern und sofort einzukaufen. Hör dir Wiedergabelisten an, die automatisch für dich erstellt werden. Schau Filme auf dem brillanten 3,5"" Display. Und kauf mit einem Fingertipp bei iTunes ein - wann immer du willst. All das und noch viel mehr mit dem iPod touch, den es schon ab 189 € gibt. Wi-Fi ist schon integriert. So kannst du im Web surfen, mailen, deinen Facebook Status aktualisieren, mit AIM chatten und noch viel mehr - und das alles auf einem Gerät, das locker in jede Tasche passt. Hier hast du die Finger im Spiel. Und nicht nur die. Denn mit den Spielen auf dem iPod touch tauchst du richtig in die Action ein - einfach neigen, tippen, drehen. Und via Wi-Fi kannst du jederzeit im App Store neue Spiele kaufen. Die iPhone 3.1 Software ist auf dem iPod touch bereits installiert, sodass der Spaß gleich beginnen kann. Damit kannst du nützliche Funktionen wie Peer-to-Peer-Spiele und Cut, Copy & Paste direkt nach dem Auspacken nutzen.
Next Level Fun: Der neue iPod touch
 
Musik
Stöber durch deine Alben. Hör dir einen einzigartigen Mix an, der nur für dich erstellt wurde. Oder schau das Video deines Lieblingssongs an. Mit dem iPod touch kannst du mehr als nur Musik hören.
 
Cover Flow
Auf dem iPod touch gibt's Musik nicht nur auf die Ohren. Mit Cover Flow ist Musik auch etwas für Augen und Finger. Dreh den iPod touch einfach auf die Seite und blätter durch deine Albumcover. Tipp auf ein Albumcover, um es umzudrehen und die Songliste zu sehen. Tipp noch einmal und Musik ab.
 
Genius Mixe
Die Genius Funktion wurde weiter verbessert. Jetzt gibt es Genius Mixe. Du brauchst den iPod touch nur mit iTunes zu synchronisieren. Genius durchsucht dann automatisch deine Mediathek nach Songs, die gut zusammenpassen und erstellt bis zu zwölf Mixe.
Diese Mixe sind wie Radiosender, auf denen nur deine Musik läuft.
 
Genius Wiedergabelisten
Angenommen du hörst einen Song auf deinem iPod touch, der dir gut gefällt, und du möchtest weitere Titel hören, die dazu passen. Genius findet weitere Songs auf deinem iPod touch und erstellt eine Genius Wiedergabeliste für dich. Hör dir die Wiedergabeliste sofort an, speichere sie für später oder versuch's noch einmal und sieh, was dabei herauskommt. Verlass dich auf Genius, wenn du einen Mix willst, auf den du selbst nie gekommen wärst.
 
Shake to Shuffle
Die Dinge mal aufrütteln. Musikalisch natürlich. Wenn du das nächste Mal Musik hörst, aktiviere die Schüttelfunktion und wenn du den iPod touch dann kurz schüttelst, springt er nach dem Zufallsprinzip zu einem anderen Song aus deiner Sammlung.
 
iTunes
Pack Musik und Videos aus der iTunes Mediathek deines Computers auf den iPod touch. Oder kauf und lade neue Songs auf den iPod touch, wenn du über Wi-Fi auf iTunes zugreifst. Wenn du den iPod touch das nächste Mal mit dem Computer verbindest, werden alle Songs, die du auf dem iPod touch gekauft hast, auf den Mac oder PC übertragen.
 
Bluetooth
Schau mal, keine Kabel. Der iPod touch enthält die iPhone 3.1 Software, sodass du Bluetooth Stereokopfhörer anschließen kannst. Lass den iPod in deiner Tasche stecken oder auf dem Schreibtisch aufladen, während du weiter Musik hörst.
 
Filme und Fernsehsendungen
Ein Kinohit. Ein Video-Podcast. Deine Lieblingsserie. Jetzt laufen sie auch in einer U-Bahn oder einem Flugzeug in deiner Nähe.
Widescreen-Display
Du kannst Videos für viele Stunden überallhin mitnehmen und auf dem gestochen scharfen 3,5"" Widescreen-Farbdisplay ansehen. Kauf im iTunes Store und wähle unter tausenden vonFilmen, Fernsehsendungen und Video-Podcasts, die du auf den iPod touch laden kannst. Von Hollywood-Hits bis zu Indie-Streifen - es gibt etwas für jeden Geschmack. Mit wenigen Fingertipps kannst du Filme kaufen und laden. Du magst lieber Fernsehsendungen? Lade eine einzelne Folge oder die gesamte Staffel.
 
On-Screen Steuerung
Auch während du Video guckst, kannst du die Steuerung einblenden - ein Fingertipp auf das Display genügt. Du kannst die Wiedergabe starten oder unterbrechen, einzelne Kapitel anzeigen und die Lautstärke anpassen. Natürlich kannst du auch die Lautstärkeregler links am iPod touch verwenden. Du willst zwischen Widescreen und bildschirmfüllender Anzeige wechseln? Einfach aufs Display doppeltippen.
 
iTunes
Du brauchst Unterhaltung für deinen nächsten Flug oder die Autofahrt? Mit iTunes auf dem iPod touch und einer Wi-Fi-Verbindung kannst du auch unterwegsFilme und Fernsehsendungen kaufen. Du kannst Filme auch leihen, wenn du dir nicht sicher bist, ob du den Film behalten willst. Und natürlich kannst du Filme und Fernsehsendungen auf dem Mac oder PC kaufen und dann mit dem iPod touch synchronisieren.
 
App Store
Kaufe im App Store und entdecke über 65.000 Apps, mit denen du noch mehr auf dem iPod touch machen kannst. Stöbere in tausenden von Apps in verschiedenen Kategorien. Von Spielen über Lifestyle und Soziale Netzwerke bis zu Unterhaltung und mehr.
 
Apps durchstöbern
Du kannst auf verschiedene Arten im App Store shoppen. Tipp auf ""Neu"" und ""Topaktuell"", um eine Liste der aktuellen und angesagten Apps zu erhalten. Stöbere nach Kategorien. Schau dir die topaktuellen Apps an. Wenn du genau weißt, wonach du suchst, kannst du auch eine Schnellsuche durchführen.
 
Genius Empfehlungen für Apps
Es gibt tausende von Apps im App Store, und jeden Tag kommen mehr dazu. Mit dieser neuen Funktion des iPod touch findest du coole neue Apps noch einfacher. Genius für Apps. Funktioniert genau wie Genius für deine Musik. Tipp auf das Genius Symbol und du bekommst Empfehlungen für Apps anhand der Apps, die du und andere schon geladen haben.
 
Apps laden
Wenn du eine App findest, die dich interessiert, kannst du sie überall, wo eine Wi-Fi-Verbindung besteht, drahtlos kaufen, auf den iPod laden und dann sofort loslegen.
 
Updates für Apps
iPod touch sagt dir, wenn ein App Update verfügbar ist, damit du immer die neuesten Versionen deiner Lieblings-Apps hast.
 
iTunes
Entdecke und lade neue Musik, Filme, Fernsehsendungen, Podcasts und Hörbücher in iTunes auf dem iPod touch.
 
Einkaufen, immer und überall
Greif über die im iPod touch integrierte Wi-Fi-Funktion auf den iTunes Store zu. Durchsuche Millionen von iTunes Plus Songs in brillanter Audioqualitätund tausende von Filmen, Fernsehsendungen, Hörbüchern und kostenlosen Podcasts und Vorlesungen von iTunes U. Stöbere nach Neuerscheinungen, Top-Titeln und Genres. Oder finde mit der Schnellsuche genau das, wonach du suchst. Hör in einen Song oder sieh dir eine Videovorschau an. Wenn du dann etwas kaufen möchtest, brauchst du nur darauf zu tippen. Nicht sicher, ob es sich lohnt, den Film zu kaufen? Dann leih ihn einfach. Alles was du auf dem iPod touch kaufst, hat denselben Preis wie im iTunes Store auf deinem Computer.
 
Synchronisieren mit iTunes
Sobald du den iPod touch mit dem Computer verbindest, werden die Songs, Filme, Fernsehsendungen, Hörbücher und Podcasts, die du unterwegs geladen hast, mit deiner iTunes Mediathek auf deinem Mac oder PC synchronisiert. Wenn du etwas nur teilweise auf den iPod touch geladen hast, beendet der Computer den Download automatisch für dich.
 
Sprachsteuerung
Mit der Sprachsteuerung beim neuen 32 GB und 64 GB iPod touch kannst du deine Musik mit Sprachbefehlen steuern. Und der iPod hört aufs Wort. Auf ""Spiel"", ""Shuffle"" oder ""Wie heißt das Lied?"".
 
Sagen und abspielen.
Die Sprachsteuerung kennt die Musik auf deinem iPod touch. Wenn du etwas Bestimmtes hören willst, sag es einfach. Zum Beispiel ""Spiel Bob Dylan"" und der iPod touch hört aufs Wort. Frag ihn, welcher Song grad läuft, und der iPod touch sagt es dir. Sag ihm, dass er dein Lieblingsalbum, deinen Lieblingssänger oder deine Lieblingswiedergabeliste spielen soll. Verwende einfache Befehle wie ""shuffle"", ""nächster Song"" und ""anhalten"". Du kannst dem iPod touch sogar sagen, dass er mehr Songs wie den, der gerade läuft, abspielen soll.
 
Sprich ins Mikro
Der neue 32 GB und 64 GB iPod touch wird mit den Apple Earphones mit Fernbedienung und Mikro geliefert. So kannst du die Sprachsteuerung auch dann nutzen, wenn der iPod touch in der Tasche steckt. Zum Aktivieren der Sprachsteuerung über die Kopfhörer hältst du einfach die Mitteltaste der Fernbedienung gedrückt.
 
Die Sprachsteuerung unterstützt die folgenden Sprachen:
Chinesisch (China), Chinesisch (Kantonesisch), Chinesisch (Taiwan), Deutsch, Englisch (Großbritannien), Englisch (USA), Finnisch, Französisch (Frankreich), Französisch (Kanada), Italienisch, Japanisch, Koreanisch, Niederländisch, Norwegisch, Polnisch, Portugiesisch (Brasilien), Portugiesisch (Portugal), Russisch, Schwedisch, Spanisch (Mexiko), Spanisch (Spanien)
 
Fotos
Der iPod touch hat für bis zu 90.000 deiner Lieblingsfotos Platz. Durch Streichen kannst du sie durchschauen und all die Erinnerst-du-dich-noch-Momente mit anderen teilen.
 
Fotos sichern
Wenn dir tolle Bilder gemailt werden, kannst du sie einfach im Fotoarchiv auf dem iPod touch sichern und dann wie jedes andere Foto nutzen. Du kannst sie zum Beispiel als Hintergrundbilder verwenden, im Internet teilen oder weitergeben.
 
Fotos teilen
Du hast tausende Fotos immer zur Hand. Blätter durch Streichen auf dem Display durch Miniaturen. Mit einem Fingertipp siehst du Fotos bildschirmfüllend. Spiel Diashows mit Musik und Übergängen ab. Maile Fotos an Freunde oder teile sie in einer MobileMe Galerie.
 
Fotos synchronisieren
Fotos aus iPhoto auf einem Mac oder Adobe Photoshop Elements und Adobe Photoshop Album auf einem PC werden via iTunes mit dem iPod touch synchronisiert. Einfach nur die Fotos und Alben aussuchen, die mit dem iPod touch synchronisiert werden sollen. Dann kannst du sie überall ansehen und mit anderen teilen.
 
Homescreen
Angenommen du möchtest ""Karten"" als erste App in der zweiten Zeile haben. Oder Mail unten im Dock. Mit den anpassbaren Homescreens kannst du den iPod touch zu deinem iPod touch machen.
 
Individuelles Anpassen
Ordne die Symbole auf deinem Homescreen an wie du willst - direkt auf dem iPod touch oder auf deinem Computer in iTunes 9. Bewege eine App eine Zeile nach oben, zwei Apps nach rechts oder auf einen anderen Homescreen. Du kannst bis zu 11 Homescreens erstellen und hast so schnellen Zugriff auf Spiele und Apps, die du aus dem App Store lädst, und auf deine Safari Weblinks.
 
Hometaste
Was auch immer du gerade mit deinem iPod touch machst – die Hometaste bringt dich immer zurück zum ersten Homescreen. Wenn du auf die Hometaste drückst, kannst du von jedem Homescreen wieder zurück zum ersten springen.
 
Apps und Weblinks hinzufügen
Für jede App, die du aus dem App Store lädst, erscheint ein neues Symbol auf dem Homescreen. Von häufig besuchten Websites kannst du praktische Weblinks erstellen. Sie erscheinen auf dem Homescreen und du kannst per Fingertipp darauf zugreifen.
 
Spotlight Suche
Du suchst was? Von einem Ort aus kannst du die gesamten Inhalte des iPod touch durchsuchen. Streich auf dem ersten Homescreen einfach nach rechts, um Spotlight zu öffnen. Sobald du anfängst zu tippen, durchsucht Spotlight deine gesamten Songs, Videos, Kontakte, Mails, Kalender, Notizen und sogar deine Hörbücher und Podcasts.
 
Safari
Safari, der fortschrittlichste Webbrowser auf einem Mobilgerät, ist auch auf dem iPod touch integriert. Damit erlebst du das Internet in deiner Hand genauso wie auf dem Computer zuhause. Alles was du brauchst ist eine Wi-Fi-Verbindung.
 
Überall ins Internet
Der iPod touch ist der einzige iPod mit integriertem drahtlosen Internetzugriff. Bei bestehender Wi-Fi-Verbindung kannst du im Internet surfen und Nachrichten lesen, Sportergebnisse sehen, Rechnungen bezahlen und online einkaufen. Und beim 32 GB oder 64 GB iPod touch wirst du sehen, dass Webseiten jetzt noch schneller als vorher geladen werden.
 
Im Web stöbern
Der iPod touch synchronisiert deine Lesezeichen vom PC oder Mac, sodass du ruckzuck auf deine Lieblingsseiten zugreifen kannst. Außerdem ist die Google- und Yahoo!-Suche schon integriert, sodass du im Web schnell findest, was du suchst.
 
Weblinks
Wenn du eine Website öfter besuchst - etwa die einer Zeitung, eines Blogs oder eine Sport-Website - kannst du einfach ein Symbol, einen sogenannten Weblink, auf dem Homescreen erstellen. Wenn du mit Safari Weblinks erstellst, sind deine Lieblingsseiten nur einen Fingertipp entfernt.
 
Zoom
Wenn du eine Website öfter besuchst, brauchst du nur mit dem Finger auf das Multi-Touch-Display zu tippen oder die Anzeige aufzuziehen. Websites lassen sich im Hoch- oder Querformat anzeigen. Einfach den iPod touch um 90 Grad drehen, und schon wird auch die Darstellung der Webseite gedreht.
 
Mail
Mails auf dem iPod touch funktionieren genau wie auf deinem Computer und sehen auch genau so aus. Und sie funktionieren mit deinen vorhandenen Accounts.
 
Nachrichten und Anhänge ansehen
Der iPod touch unterstützt Rich-HTML-E-Mail, sodass Bilder und Fotos zusammen mit dem Text einer E-Mail angezeigt werden. Anhänge siehst du in ihrem Originalformat und nicht als abgespeckte Version. Du kannst in mehr als einem Dutzend standardmäßigen Datei- und Bildformaten drehen, zoomen und schwenken, darunter PDF, Microsoft Word, Excel, PowerPoint und iWork.
 
Zugriff auf alle Accounts
Mails von gängigen Anbietern wie MobileMe, Google Mail, Microsoft Exchange, Yahoo! und den meisten standardmäßigen IMAP- und POP-Systemen kannst du mit dem iPod touch ganz einfach abrufen.
 
Schnellere Eingabe
Der iPod touch erkennt E-Mail-Adressen in verschiedenen Programmen. Wenn du auf einer Webseite oder in einer Karte eine E-Mail-Adresse siehst, reicht ein Fingertipp auf dem iPod touch, um eine neue Mail zu öffnen, in der die Adresse bereits eingetragen ist.
 
Intelligente Eingabe
Die innovative iPod touch Tastatur mit integriertem Wörterbuch* schlägt während der Eingabe Wörter vor. So kannst du ganz schnell und einfach Mails schreiben. Dreh den iPod touch einfach. Dann wird die Tastatur vom Hochformat ins Querformat gedreht und du hast größere Tasten und mehr Platz zum Tippen.
 
Postfach durchsuchen
Du musst das Postfach jetzt nicht mehr Mail für Mail durchsuchen. Durch schnelles Abwärtsstreichen wird jetzt ein Suchfeld geöffnet, mit dem du deine Mails nach Absender, Empfänger, Betreff oder Titelzeilen durchsuchen kannst.
 
Karten
Finde deinen Weg und die nächste Pizzeria. Mit Karten und einer Wi-Fi-Verbindung kannst du Wegbeschreibungen abrufen, Firmen finden und Verkehrsinformationen prüfen.
 
Finde dich selbst
Der iPod touch zeigt dir mithilfe von bekannten Wi-Fi-Hot-Spots, wo du bist. Mit der Stichwortsuche kannst du auch interessante Orte finden. Wenn du z. B. ""Kaffee"" eingibst, werden dir alle Cafés in der Nähe angezeigt.
 
Wo geht's lang?
Gib einfach eine Adresse ein, um Wegbeschreibungen abzurufen - von jedem Ort aus. Wähle das Transportmittel wie Auto, öffentliches Verkehrsmittel oder zu Fuß. Die Route lässt sich dann Schritt für Schritt anzeigen. Du kannst dem markierten Weg auf der Karte folgen und selbst die Fahrtdauer wird angezeigt. Oder markiere zwei Orte und lass dir die beste Route zwischen diesen anzeigen.
 
Verschiedene Kartendarstellungen
Wie bei Google Karten auf deinem Computer kannst du mit dem Programm ""Karten"" auf dem iPod touch zwischen unterschiedlichen Darstellungen von Google-Karten, Satellitenbildern und einer Hybriddarstellung wechseln. Und mit Multi-Touch kannst du unterwegs zoomen, den Ausschnitt bewegen und die Darstellung ändern.
 
Verkehrsinformationen
Die Verkehrsinformationen geben dir anhand der grünen, roten und gelben Markierungen einen Überblick über die Verkehrssituation auf deiner Route.
 
YouTube
Skateboard Moves, die so nicht geplant waren. Witzige Werbespots aus anderen Ländern. Was auch immer du gern auf YouTube ansiehst - der iPod touch ist für dich da.
 
Videogrüße von unterwegs.
Maile Links deiner Lieblingsvideos an Freunde. Tippe auf der Detailseite des YouTube Videos auf ""Senden"", und schon erstellt der iPod touch eine Mail mit dem zugehörigen Videolink.
 
Auf YouTube suchen.
Stöber in Videokategorien wie ""Highlights"", ""Topvideos"", ""Neue Videos"" oder ""Bestwertung"". Du kannst auch per Schlagwort nach einem Video suchen. Etwas Passendes gefunden? Mit einem Lesezeichen kannst du das Video auch vormerken und später ansehen.
 
Nike + iPod Kompatibilität
Rock dein Training. Der iPod touch hat eine integrierte Unterstützung für Nike + iPod. Das ist Musik und Motivation in einem.
Finetuning für dein Lauftraining.
 
Nike + iPod Sensor
Der iPod touch hat eine integrierte Unterstützung für Nike + iPod. Einfach den Nike + iPod Sensor (separat erhältlich) in die Nike+ Schuhe stecken und los geht's. Der Sensor überträgt deine Laufdaten drahtlos an den iPod touch und zeichnet Laufzeit, Laufstrecke und Kalorienverbrauch auf. Du erhältst sogar Feedback zum Trainingsfortschritt.
 
Finetuning für dein Cardio Workout
Diese Funktion kann auch zusammen mit neuen, in vielen Fitnessstudios vorhandenen Geräten für das Ausdauertraining gekoppelt werden. Such dir einfach ein mit Nike + iPod kompatibles Fitnessgerät wie beispielsweise Laufbänder, Ellipsentrainer, Stepper und Hometrainer.
 
Synchronisieren mit nikeplus.com
Später kannst du am Computer den iPod touch via iTunes synchronisieren und deine Trainingsdaten an nikeplus.com übertragen. Auf dieser Website kannst du dein Training verfolgen, dir Ziele setzen und deine Freunde herausfordern.
 
Sprachmemos
Du hast vielleicht ein ganz gutes Gedächtnis, aber manchmal ist es besser, kleine (und große) Infos einfach irgendwo festzuhalten. Mit ""Sprachmemos"" kein Problem.
 
Memos (oder alles andere)aufnehmen
Nimm eine Aufgabenliste, geniale Ideen oder eine Wette zwischen dir und deinem Freund auf. Mit dem Programm ""Sprachmemos"" kannst du über die Apple Earphones mit Fernbedienung und Mikro oder ein externes Mikrofon aufnehmen, was immer du willst. Sprachmemos kannst du selbst dann aufnehmen, wenn du den iPod touch gerade verwendest, um Mails zu checken oder im Web zu surfen.
 
Memos bearbeiten
Aufgenommene Memos kannst du direkt auf dem iPod touch trimmen. So behältst du nur das, was du wirklich brauchst.
 
Memos sortieren
Ordne deine Memos mithilfe von Etiketten aus einer vordefinierten Liste oder erstelle eigene Etiketten.
 
Memos teilen
Maile Memos an Freunde und Kollegen. Mit dem iPod touch aufgenommene Memos werden via iTunes mit deinem Mac oder PC synchronisiert, damit du sie später mit anderen teilen kannst.
 
Weitere Funktionen
Auf dem iPod touch ist die neueste Software schon installiert. Und außerdem gibt's praktische Apps wie Kontakte, Kalender, Notizen, Aktien und Wetter.
 
iPod touch 3.1 Softwarefunktionen.
 
Genius Mixe
Diese neue Funktion ist wie ein privater DJ, der deine iTunes Mediathek durchsucht, um Songs zu finden, die gut zusammenpassen und aus diesen dann tolle Mixe erstellt. Alles ganz automatisch.
 
Genius Empfehlungen für Apps
Im App Store gibt's zehntausende Apps. Wie soll man da die richtig collen neuen finden? Mit Genius. Denn Genius sieht sich die Apps an, die du schon hast, und empfiehlt dir weitere.
 
Peer-to-Peer-Spiele
Die neusten Spiele kannst du ganz leicht mit Freunden spielen - egal, ob sie neben dir oder in einer anderen Ecke des Landes sitzen.
 
Kauf Filme, Fernsehsendungen und Hörbücher via Wi-Fi
Lade via Wi-Fi Filme, Fernsehsendungen, Musikvideos und Hörbücher aus dem iTunes Store auf deinen iPod touch.
 
Tastatur im Querformat
Du brauchst mehr Platz zum Tippen? Dreh den iPod touch ins Querformat, um in Mail, Notizen und Safari mit einer größeren Tastatur zu arbeiten.
 
Cut, Copy & Paste
Einfach Text und Fotos ausschneiden, kopieren und wieder einsetzen - selbst zwischen Programmen. Du kannst auch Inhalte aus dem Web kopieren.
 
Spotlight Suche
Gesucht, gefunden - von einem Ort aus. Spotlight durchsucht alle deine Kontakte, E-Mails, Kalender und Notizen und auch alle Songs und Videos.
 
Stereo Bluetooth
Hör Musik und andere Audioinhalte drahtlos. Verbinde den iPod touch mit kompatiblen Bluetooth Stereokopfhörern.
 
Automatischer Wi-Fi-Login
Wenn du dich einmal bei einem Wi-Fi-Hotspot anmeldest, loggt der iPod touch sich beim nächsten Mal automatisch ein.
 
Shake to Shuffle
Schüttel den iPod kurz, und schon springt er nach dem Zufallsprinzip zu einem anderen Song in deiner Sammlung. Lass dich einfach überraschen.
 
Bedienungshilfen
Der neue iPod touch hat standardmäßig Bedienungshilfen integriert, mit denen auch Menschen mit Beeinträchtigungen alles, was der iPod touch zu bieten hat, erleben können. Alle Bedienungshilfen des iPod touch ansehen
 
Kindersicherung
Du entscheidest, welche Musik, Videos und Apps auf dem iPod touch für deine Kinder geeignet sind.
Der iPod touch hat auch die folgenden praktischen Apps:
 
Kalender
Das Programm ""Kalender"" funktioniert mit Yahoo!, Google, Microsoft Outlook, iCal, MobileMe und Microsoft Exchange ActiveSync für Unternehmen. Füge Termine hinzu, lass dich an Termine erinnern, und abonniere Kalender, damit du über Feiertage und Sportveranstaltungen auf dem Laufenden bleibst.
 
Kontakte
Namen, E-Mail-Adressen, Telefonnummern und mehr - immer zur Hand. Synchronisier Kontakte in iTunes auf dem Mac oder PC mit dem iPod touch. Neue Kontakte kannst du auch unterwegs mit einem einfachen Fingertipp hinzufügen.
 
Notizen
Schluss mit Papier und Bleistift. Mach dir mit ""Notizen"" auf dem iPod schnell eine Notiz, damit du wichtige Infos immer parat hast. Maile deine Gedanken mit der integrierten Mail-Funktion an dich oder andere.
 
Aktien
Die Aktien App auf dem iPod touch zeigt dir Börseninformationen für die Aktien, die dich interessieren. Wenn du nähere Details über eine Aktie brauchst, tipp auf ""Y!"", um im Handumdrehen Yahoo! Finance zu öffnen.
 
Wetter
Informier dich über das Wetter in der ganzen Welt oder zuhause. Füge die gewünschten Städte hinzu und zeige eine sechstägige Vorhersage für alle an. Tipp auf ""Y!"", um den Yahoo! Stadtführer zu öffnen, der dir zeigt, wo was los ist.
 
Rechner
Im Programm ""Rechner"" des iPod touch stecken gleich zwei Rechner. Im Hochformat kannst du ihn als einfachen Taschenrechner verwenden. Dreh den iPod touch ins Querformat, um aus ihm einen wissenschaftlichen Rechner zu machen.
 
iPod touch Technologie
Dank der revolutionären Hardwaretechnologie im iPod touch kannst du alle Funktionen mit Streichen, Tippen und Auf- oder Zuziehen steuern. Deswegen wirkt das Autorennen so echt. Deswegen kannst du das, was du eben im Café mitbekommen hast, sofort twittern. Und genau deswegen ist der iPod touch der beste iPod aller Zeiten.
 
Multi-Touch
Das Multi-Touch-Display besitzt einen Schutzfilm über der kapazitiven Sensorik, die Berührungen anhand elektrischer Felder erkennt. Diese Informationen werden an das darunterliegende LCD-Display übertragen. Dank der Software des iPod touch kannst du mit Cover Flow durch Alben stöbern, durch deine Fotos blättern, mit Auf- und Zuziehen Bildausschnitte von Websites zoomen und Spiele superpräzise steuern.
 
Beschleunigungssensor
Der iPod touch reagiert über einen integrierten Beschleunigungssensor auf Bewegungen. Dieser Sensor erkennt, wenn du deinen iPod touch ins Querformat drehst und verändert automatisch den Inhalt des Displays. Die Technologie des Beschleunigungssensors kommt besonders bei Spielen gut, denn damit bist du mitten im Spielgeschehen. Das ist perfekt für Autorennen, bei denen der ganze iPod zum Lenkrad wird, und Geschicklichkeitsspiele wie Rolando, bei denen du das Spiel mit deinen Bewegungen steuerst
 
Drahtlos
Der iPod touch hat eine integrierte Unterstützung für drahtlosen 802.11b/g Internetzugriff. Überall, wo es ein Wi-Fi-Netzwerk gibt, kommst du mit deinem iPod touch ins Internet. Im Café mailen. Am Flughafen im Web surfen. Spiele vom Sofa aus kaufen. Im iTunes Store stöbern und Musik kaufen und laden. Der iPod touch findet nahegelegene Wi-Fi-Hot-Spots, auch geschützte Netzwerke. Wenn du ein bestimmtes Netzwerk bisher noch nicht verwendet hast, Drahtlos Symbol musst du beim ersten Mal ein Kennwort eingeben, das sich der iPod touch dann merkt. Wenn du dann das nächste Mal in Reichweite dieses Netzwerks bist, loggt er sich automatisch ein.
 
Bluetooth
Bluetooth ist eine drahtlose Technologie, mit der du Geräte ohne lästige Kabel verwenden kannst. Was bedeutet das für den iPod touch? Du kannst jetzt mit dem iPod touch und Bluetooth Kopfhörern Musik hören, ganz egal, wo im Raum der iPod ist. Du kannst also auf dem Bett relaxen, während der iPod auf dem Schreibtisch aufgeladen wird. Bluetooth auf dem iPod touch eignet sich auch besonders für Peer-to-Peer-Spiele.
 
Design
Der iPod touch ist von außen genau so großartig wie von innen. Du brauchst nur einen in die Hand zu nehmen. Das Gehäuse des iPod touch ist gerade einmal 8,5 mm hoch. Das optische Glas auf der Vorderseite und die Rückseite aus poliertem Edelstahl geben ihm einen eleganten Touch und fühlen sich in der Hand einfach gut an. Schalte ihn ein und du wirst über das brillante 3,5"" Display einfach staunen. Der iPod touch ist die perfekte Kombination aus großartigem Design und revolutionärer Technologie - das perfekte Paket.
";2;False;0;;;Apple iPod Touch schwarz mit integrierter WiFi Funktion;apple-ipod-touch-32-gb-schwarz-2;True;True;P-1290;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;269.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40186,8623263889;44;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000434-apple-ipod-touch-64-gb-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000435-apple-ipod-touch-64-gb-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000436-apple-ipod-touch-64-gb-schwarz.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Apple iPod Touch 64 GB schwarz;Apple iPod Touch 64 GB schwarz;"
Apple iPod Touch 64 GB schwarz
mit integrierter WiFi Funktion


Ein großartiger iPod. Ein großartiger Taschencomputer. Großartiger mobiler Spielspaß. Und das Ganze in einem unglaublich schlanken, eleganten neuen Design aus Edelstahl. Filme, Videos und Fernsehsendungen auf einem 3,5"" Display ansehen!
Im Web surfen, mailen!
Multitouch-Oberfläche: Die revolutionäre Technologie des iPhone und die Software Version 3.1 stecken in diesem genialen iPod. Das brillante Breitformat-Display rückt Ihre Videos und Spiele ins beste Licht
Surfen Sie mit Safari im Web und sehen Sie YouTube Videos auf dem iPod mit integrierter Wi-Fi Funktionalität an.
Mit Ihrem iPod touch können Sie im iTunes Wi-Fi Music Store nach Songs suchen, Hörproben abspielen und Titel kaufen. Lieferumfang: iPod touch, Ohrhörer, USB 2.0 Kabel, Dock-Adapter, Kurzanleitung
 
Der iPod touch kann alles, was du am iPod toll findest. Und noch vielmehr.
Du kannst Filme, Videos und Fernsehsendungen auf einem 3,5"" Display ansehen. Mit der revolutionären Multi-Touch-Technologie kannst du dein Musikarchiv mit Cover Flow durchblättern. Und wenn dir nach mehr ist, tipp einfach auf iTunes, um durch das Angebot zu stöbern und sofort einzukaufen. Hör dir Wiedergabelisten an, die automatisch für dich erstellt werden. Schau Filme auf dem brillanten 3,5"" Display. Und kauf mit einem Fingertipp bei iTunes ein - wann immer du willst. All das und noch viel mehr mit dem iPod touch, den es schon ab 189 € gibt. Wi-Fi ist schon integriert. So kannst du im Web surfen, mailen, deinen Facebook Status aktualisieren, mit AIM chatten und noch viel mehr - und das alles auf einem Gerät, das locker in jede Tasche passt. Hier hast du die Finger im Spiel. Und nicht nur die. Denn mit den Spielen auf dem iPod touch tauchst du richtig in die Action ein - einfach neigen, tippen, drehen. Und via Wi-Fi kannst du jederzeit im App Store neue Spiele kaufen. Die iPhone 3.1 Software ist auf dem iPod touch bereits installiert, sodass der Spaß gleich beginnen kann. Damit kannst du nützliche Funktionen wie Peer-to-Peer-Spiele und Cut, Copy & Paste direkt nach dem Auspacken nutzen.
Next Level Fun: Der neue iPod touch
 
Musik
Stöber durch deine Alben. Hör dir einen einzigartigen Mix an, der nur für dich erstellt wurde. Oder schau das Video deines Lieblingssongs an. Mit dem iPod touch kannst du mehr als nur Musik hören.
 
Cover Flow
Auf dem iPod touch gibt's Musik nicht nur auf die Ohren. Mit Cover Flow ist Musik auch etwas für Augen und Finger. Dreh den iPod touch einfach auf die Seite und blätter durch deine Albumcover. Tipp auf ein Albumcover, um es umzudrehen und die Songliste zu sehen. Tipp noch einmal und Musik ab.
 
Genius Mixe
Die Genius Funktion wurde weiter verbessert. Jetzt gibt es Genius Mixe. Du brauchst den iPod touch nur mit iTunes zu synchronisieren. Genius durchsucht dann automatisch deine Mediathek nach Songs, die gut zusammenpassen und erstellt bis zu zwölf Mixe.
Diese Mixe sind wie Radiosender, auf denen nur deine Musik läuft.
 
Genius Wiedergabelisten
Angenommen du hörst einen Song auf deinem iPod touch, der dir gut gefällt, und du möchtest weitere Titel hören, die dazu passen. Genius findet weitere Songs auf deinem iPod touch und erstellt eine Genius Wiedergabeliste für dich. Hör dir die Wiedergabeliste sofort an, speichere sie für später oder versuch's noch einmal und sieh, was dabei herauskommt. Verlass dich auf Genius, wenn du einen Mix willst, auf den du selbst nie gekommen wärst.
 
Shake to Shuffle
Die Dinge mal aufrütteln. Musikalisch natürlich. Wenn du das nächste Mal Musik hörst, aktiviere die Schüttelfunktion und wenn du den iPod touch dann kurz schüttelst, springt er nach dem Zufallsprinzip zu einem anderen Song aus deiner Sammlung.

iTunes
Pack Musik und Videos aus der iTunes Mediathek deines Computers auf den iPod touch. Oder kauf und lade neue Songs auf den iPod touch, wenn du über Wi-Fi auf iTunes zugreifst. Wenn du den iPod touch das nächste Mal mit dem Computer verbindest, werden alle Songs, die du auf dem iPod touch gekauft hast, auf den Mac oder PC übertragen.
 
Bluetooth
Schau mal, keine Kabel. Der iPod touch enthält die iPhone 3.1 Software, sodass du Bluetooth Stereokopfhörer anschließen kannst. Lass den iPod in deiner Tasche stecken oder auf dem Schreibtisch aufladen, während du weiter Musik hörst.
 
Filme und Fernsehsendungen
Ein Kinohit. Ein Video-Podcast. Deine Lieblingsserie. Jetzt laufen sie auch in einer U-Bahn oder einem Flugzeug in deiner Nähe.
 
Widescreen-Display
Du kannst Videos für viele Stunden überallhin mitnehmen und auf dem gestochen scharfen 3,5"" Widescreen-Farbdisplay ansehen. Kauf im iTunes Store und wähle unter tausenden vonFilmen, Fernsehsendungen und Video-Podcasts, die du auf den iPod touch laden kannst. Von Hollywood-Hits bis zu Indie-Streifen - es gibt etwas für jeden Geschmack. Mit wenigen Fingertipps kannst du Filme kaufen und laden. Du magst lieber Fernsehsendungen? Lade eine einzelne Folge oder die gesamte Staffel.
 
On-Screen Steuerung
Auch während du Video guckst, kannst du die Steuerung einblenden - ein Fingertipp auf das Display genügt. Du kannst die Wiedergabe starten oder unterbrechen, einzelne Kapitel anzeigen und die Lautstärke anpassen. Natürlich kannst du auch die Lautstärkeregler links am iPod touch verwenden. Du willst zwischen Widescreen und bildschirmfüllender Anzeige wechseln? Einfach aufs Display doppeltippen.
 
iTunes
Du brauchst Unterhaltung für deinen nächsten Flug oder die Autofahrt? Mit iTunes auf dem iPod touch und einer Wi-Fi-Verbindung kannst du auch unterwegsFilme und Fernsehsendungen kaufen. Du kannst Filme auch leihen, wenn du dir nicht sicher bist, ob du den Film behalten willst. Und natürlich kannst du Filme und Fernsehsendungen auf dem Mac oder PC kaufen und dann mit dem iPod touch synchronisieren.
 
App Store
Kaufe im App Store und entdecke über 65.000 Apps, mit denen du noch mehr auf dem iPod touch machen kannst. Stöbere in tausenden von Apps in verschiedenen Kategorien. Von Spielen über Lifestyle und Soziale Netzwerke bis zu Unterhaltung und mehr.
 
Apps durchstöbern
Du kannst auf verschiedene Arten im App Store shoppen. Tipp auf ""Neu"" und ""Topaktuell"", um eine Liste der aktuellen und angesagten Apps zu erhalten. Stöbere nach Kategorien. Schau dir die topaktuellen Apps an. Wenn du genau weißt, wonach du suchst, kannst du auch eine Schnellsuche durchführen.
 
Genius Empfehlungen für Apps
Es gibt tausende von Apps im App Store, und jeden Tag kommen mehr dazu. Mit dieser neuen Funktion des iPod touch findest du coole neue Apps noch einfacher. Genius für Apps. Funktioniert genau wie Genius für deine Musik. Tipp auf das Genius Symbol und du bekommst Empfehlungen für Apps anhand der Apps, die du und andere schon geladen haben.
 
Apps laden
Wenn du eine App findest, die dich interessiert, kannst du sie überall, wo eine Wi-Fi-Verbindung besteht, drahtlos kaufen, auf den iPod laden und dann sofort loslegen.
 
Updates für Apps
iPod touch sagt dir, wenn ein App Update verfügbar ist, damit du immer die neuesten Versionen deiner Lieblings-Apps hast.
 
iTunes
Entdecke und lade neue Musik, Filme, Fernsehsendungen, Podcasts und Hörbücher in iTunes auf dem iPod touch.
 
Einkaufen, immer und überall
Greif über die im iPod touch integrierte Wi-Fi-Funktion auf den iTunes Store zu. Durchsuche Millionen von iTunes Plus Songs in brillanter Audioqualitätund tausende von Filmen, Fernsehsendungen, Hörbüchern und kostenlosen Podcasts und Vorlesungen von iTunes U. Stöbere nach Neuerscheinungen, Top-Titeln und Genres. Oder finde mit der Schnellsuche genau das, wonach du suchst. Hör in einen Song oder sieh dir eine Videovorschau an. Wenn du dann etwas kaufen möchtest, brauchst du nur darauf zu tippen. Nicht sicher, ob es sich lohnt, den Film zu kaufen? Dann leih ihn einfach. Alles was du auf dem iPod touch kaufst, hat denselben Preis wie im iTunes Store auf deinem Computer.
 
Synchronisieren mit iTunes
Sobald du den iPod touch mit dem Computer verbindest, werden die Songs, Filme, Fernsehsendungen, Hörbücher und Podcasts, die du unterwegs geladen hast, mit deiner iTunes Mediathek auf deinem Mac oder PC synchronisiert. Wenn du etwas nur teilweise auf den iPod touch geladen hast, beendet der Computer den Download automatisch für dich.
 
Sprachsteuerung
Mit der Sprachsteuerung beim neuen 32 GB und 64 GB iPod touch kannst du deine Musik mit Sprachbefehlen steuern. Und der iPod hört aufs Wort. Auf ""Spiel"", ""Shuffle"" oder ""Wie heißt das Lied?"".
Sagen und abspielen.
Die Sprachsteuerung kennt die Musik auf deinem iPod touch. Wenn du etwas Bestimmtes hören willst, sag es einfach. Zum Beispiel ""Spiel Bob Dylan"" und der iPod touch hört aufs Wort. Frag ihn, welcher Song grad läuft, und der iPod touch sagt es dir. Sag ihm, dass er dein Lieblingsalbum, deinen Lieblingssänger oder deine Lieblingswiedergabeliste spielen soll. Verwende einfache Befehle wie ""shuffle"", ""nächster Song"" und ""anhalten"". Du kannst dem iPod touch sogar sagen, dass er mehr Songs wie den, der gerade läuft, abspielen soll.
 
Sprich ins Mikro
Der neue 32 GB und 64 GB iPod touch wird mit den Apple Earphones mit Fernbedienung und Mikro geliefert. So kannst du die Sprachsteuerung auch dann nutzen, wenn der iPod touch in der Tasche steckt. Zum Aktivieren der Sprachsteuerung über die Kopfhörer hältst du einfach die Mitteltaste der Fernbedienung gedrückt.
Die Sprachsteuerung unterstützt die folgenden Sprachen:
Chinesisch (China), Chinesisch (Kantonesisch), Chinesisch (Taiwan), Deutsch, Englisch (Großbritannien), Englisch (USA), Finnisch, Französisch (Frankreich), Französisch (Kanada), Italienisch, Japanisch, Koreanisch, Niederländisch, Norwegisch, Polnisch, Portugiesisch (Brasilien), Portugiesisch (Portugal), Russisch, Schwedisch, Spanisch (Mexiko), Spanisch (Spanien)
 
Fotos
Der iPod touch hat für bis zu 90.000 deiner Lieblingsfotos Platz. Durch Streichen kannst du sie durchschauen und all die Erinnerst-du-dich-noch-Momente mit anderen teilen.
 
Fotos sichern
Wenn dir tolle Bilder gemailt werden, kannst du sie einfach im Fotoarchiv auf dem iPod touch sichern und dann wie jedes andere Foto nutzen. Du kannst sie zum Beispiel als Hintergrundbilder verwenden, im Internet teilen oder weitergeben.
 
Fotos teilen
Du hast tausende Fotos immer zur Hand. Blätter durch Streichen auf dem Display durch Miniaturen. Mit einem Fingertipp siehst du Fotos bildschirmfüllend. Spiel Diashows mit Musik und Übergängen ab. Maile Fotos an Freunde oder teile sie in einer MobileMe Galerie.
 
Fotos synchronisieren
Fotos aus iPhoto auf einem Mac oder Adobe Photoshop Elements und Adobe Photoshop Album auf einem PC werden via iTunes mit dem iPod touch synchronisiert. Einfach nur die Fotos und Alben aussuchen, die mit dem iPod touch synchronisiert werden sollen. Dann kannst du sie überall ansehen und mit anderen teilen.

Homescreen
Angenommen du möchtest ""Karten"" als erste App in der zweiten Zeile haben. Oder Mail unten im Dock. Mit den anpassbaren Homescreens kannst du den iPod touch zu deinem iPod touch machen.
 
Individuelles Anpassen
Ordne die Symbole auf deinem Homescreen an wie du willst - direkt auf dem iPod touch oder auf deinem Computer in iTunes 9. Bewege eine App eine Zeile nach oben, zwei Apps nach rechts oder auf einen anderen Homescreen. Du kannst bis zu 11 Homescreens erstellen und hast so schnellen Zugriff auf Spiele und Apps, die du aus dem App Store lädst, und auf deine Safari Weblinks.
 
Hometaste
Was auch immer du gerade mit deinem iPod touch machst – die Hometaste bringt dich immer zurück zum ersten Homescreen. Wenn du auf die Hometaste drückst, kannst du von jedem Homescreen wieder zurück zum ersten springen.
 
Apps und Weblinks hinzufügen
Für jede App, die du aus dem App Store lädst, erscheint ein neues Symbol auf dem Homescreen. Von häufig besuchten Websites kannst du praktische Weblinks erstellen. Sie erscheinen auf dem Homescreen und du kannst per Fingertipp darauf zugreifen.
 
Spotlight Suche
Du suchst was? Von einem Ort aus kannst du die gesamten Inhalte des iPod touch durchsuchen. Streich auf dem ersten Homescreen einfach nach rechts, um Spotlight zu öffnen. Sobald du anfängst zu tippen, durchsucht Spotlight deine gesamten Songs, Videos, Kontakte, Mails, Kalender, Notizen und sogar deine Hörbücher und Podcasts.
 
Safari
Safari, der fortschrittlichste Webbrowser auf einem Mobilgerät, ist auch auf dem iPod touch integriert. Damit erlebst du das Internet in deiner Hand genauso wie auf dem Computer zuhause. Alles was du brauchst ist eine Wi-Fi-Verbindung.
 
Überall ins Internet
Der iPod touch ist der einzige iPod mit integriertem drahtlosen Internetzugriff. Bei bestehender Wi-Fi-Verbindung kannst du im Internet surfen und Nachrichten lesen, Sportergebnisse sehen, Rechnungen bezahlen und online einkaufen. Und beim 32 GB oder 64 GB iPod touch wirst du sehen, dass Webseiten jetzt noch schneller als vorher geladen werden.
 
Im Web stöbern
Der iPod touch synchronisiert deine Lesezeichen vom PC oder Mac, sodass du ruckzuck auf deine Lieblingsseiten zugreifen kannst. Außerdem ist die Google- und Yahoo!-Suche schon integriert, sodass du im Web schnell findest, was du suchst.
 
Weblinks
Wenn du eine Website öfter besuchst - etwa die einer Zeitung, eines Blogs oder eine Sport-Website - kannst du einfach ein Symbol, einen sogenannten Weblink, auf dem Homescreen erstellen. Wenn du mit Safari Weblinks erstellst, sind deine Lieblingsseiten nur einen Fingertipp entfernt.
 
Zoom
Wenn du eine Website öfter besuchst, brauchst du nur mit dem Finger auf das Multi-Touch-Display zu tippen oder die Anzeige aufzuziehen. Websites lassen sich im Hoch- oder Querformat anzeigen. Einfach den iPod touch um 90 Grad drehen, und schon wird auch die Darstellung der Webseite gedreht.
 
Mail
Mails auf dem iPod touch funktionieren genau wie auf deinem Computer und sehen auch genau so aus. Und sie funktionieren mit deinen vorhandenen Accounts.
 
Nachrichten und Anhänge ansehen
Der iPod touch unterstützt Rich-HTML-E-Mail, sodass Bilder und Fotos zusammen mit dem Text einer E-Mail angezeigt werden. Anhänge siehst du in ihrem Originalformat und nicht als abgespeckte Version. Du kannst in mehr als einem Dutzend standardmäßigen Datei- und Bildformaten drehen, zoomen und schwenken, darunter PDF, Microsoft Word, Excel, PowerPoint und iWork.
 
Zugriff auf alle Accounts
Mails von gängigen Anbietern wie MobileMe, Google Mail, Microsoft Exchange, Yahoo! und den meisten standardmäßigen IMAP- und POP-Systemen kannst du mit dem iPod touch ganz einfach abrufen.
 
Schnellere Eingabe
Der iPod touch erkennt E-Mail-Adressen in verschiedenen Programmen. Wenn du auf einer Webseite oder in einer Karte eine E-Mail-Adresse siehst, reicht ein Fingertipp auf dem iPod touch, um eine neue Mail zu öffnen, in der die Adresse bereits eingetragen ist.
 
Intelligente Eingabe
Die innovative iPod touch Tastatur mit integriertem Wörterbuch* schlägt während der Eingabe Wörter vor. So kannst du ganz schnell und einfach Mails schreiben. Dreh den iPod touch einfach. Dann wird die Tastatur vom Hochformat ins Querformat gedreht und du hast größere Tasten und mehr Platz zum Tippen.
 
Postfach durchsuchen
Du musst das Postfach jetzt nicht mehr Mail für Mail durchsuchen. Durch schnelles Abwärtsstreichen wird jetzt ein Suchfeld geöffnet, mit dem du deine Mails nach Absender, Empfänger, Betreff oder Titelzeilen durchsuchen kannst.
 
Karten
Finde deinen Weg und die nächste Pizzeria. Mit Karten und einer Wi-Fi-Verbindung kannst du Wegbeschreibungen abrufen, Firmen finden und Verkehrsinformationen prüfen.
 
Finde dich selbst
Der iPod touch zeigt dir mithilfe von bekannten Wi-Fi-Hot-Spots, wo du bist. Mit der Stichwortsuche kannst du auch interessante Orte finden. Wenn du z. B. ""Kaffee"" eingibst, werden dir alle Cafés in der Nähe angezeigt.
 
Wo geht's lang?
Gib einfach eine Adresse ein, um Wegbeschreibungen abzurufen - von jedem Ort aus. Wähle das Transportmittel wie Auto, öffentliches Verkehrsmittel oder zu Fuß. Die Route lässt sich dann Schritt für Schritt anzeigen. Du kannst dem markierten Weg auf der Karte folgen und selbst die Fahrtdauer wird angezeigt. Oder markiere zwei Orte und lass dir die beste Route zwischen diesen anzeigen.
 
Verschiedene Kartendarstellungen
Wie bei Google Karten auf deinem Computer kannst du mit dem Programm ""Karten"" auf dem iPod touch zwischen unterschiedlichen Darstellungen von Google-Karten, Satellitenbildern und einer Hybriddarstellung wechseln. Und mit Multi-Touch kannst du unterwegs zoomen, den Ausschnitt bewegen und die Darstellung ändern.
 
Verkehrsinformationen
Die Verkehrsinformationen geben dir anhand der grünen, roten und gelben Markierungen einen Überblick über die Verkehrssituation auf deiner Route.
 
YouTube
Skateboard Moves, die so nicht geplant waren. Witzige Werbespots aus anderen Ländern. Was auch immer du gern auf YouTube ansiehst - der iPod touch ist für dich da.
 
Videogrüße von unterwegs.
Maile Links deiner Lieblingsvideos an Freunde. Tippe auf der Detailseite des YouTube Videos auf ""Senden"", und schon erstellt der iPod touch eine Mail mit dem zugehörigen Videolink.
 
Auf YouTube suchen.
Stöber in Videokategorien wie ""Highlights"", ""Topvideos"", ""Neue Videos"" oder ""Bestwertung"". Du kannst auch per Schlagwort nach einem Video suchen. Etwas Passendes gefunden? Mit einem Lesezeichen kannst du das Video auch vormerken und später ansehen.
 
Nike + iPod Kompatibilität
Rock dein Training. Der iPod touch hat eine integrierte Unterstützung für Nike + iPod. Das ist Musik und Motivation in einem.
Finetuning für dein Lauftraining.
 
Nike + iPod Sensor
Der iPod touch hat eine integrierte Unterstützung für Nike + iPod. Einfach den Nike + iPod Sensor (separat erhältlich) in die Nike+ Schuhe stecken und los geht's. Der Sensor überträgt deine Laufdaten drahtlos an den iPod touch und zeichnet Laufzeit, Laufstrecke und Kalorienverbrauch auf. Du erhältst sogar Feedback zum Trainingsfortschritt.
 
Finetuning für dein Cardio Workout
Diese Funktion kann auch zusammen mit neuen, in vielen Fitnessstudios vorhandenen Geräten für das Ausdauertraining gekoppelt werden. Such dir einfach ein mit Nike + iPod kompatibles Fitnessgerät wie beispielsweise Laufbänder, Ellipsentrainer, Stepper und Hometrainer.
 
Synchronisieren mit nikeplus.com
Später kannst du am Computer den iPod touch via iTunes synchronisieren und deine Trainingsdaten an nikeplus.com übertragen. Auf dieser Website kannst du dein Training verfolgen, dir Ziele setzen und deine Freunde herausfordern.
 
Sprachmemos
Du hast vielleicht ein ganz gutes Gedächtnis, aber manchmal ist es besser, kleine (und große) Infos einfach irgendwo festzuhalten. Mit ""Sprachmemos"" kein Problem.

Memos (oder alles andere)aufnehmen
Nimm eine Aufgabenliste, geniale Ideen oder eine Wette zwischen dir und deinem Freund auf. Mit dem Programm ""Sprachmemos"" kannst du über die Apple Earphones mit Fernbedienung und Mikro oder ein externes Mikrofon aufnehmen, was immer du willst. Sprachmemos kannst du selbst dann aufnehmen, wenn du den iPod touch gerade verwendest, um Mails zu checken oder im Web zu surfen.
Memos bearbeiten
Aufgenommene Memos kannst du direkt auf dem iPod touch trimmen. So behältst du nur das, was du wirklich brauchst.
Memos sortieren
Ordne deine Memos mithilfe von Etiketten aus einer vordefinierten Liste oder erstelle eigene Etiketten.
Memos teilen
Maile Memos an Freunde und Kollegen. Mit dem iPod touch aufgenommene Memos werden via iTunes mit deinem Mac oder PC synchronisiert, damit du sie später mit anderen teilen kannst.
Weitere Funktionen
Auf dem iPod touch ist die neueste Software schon installiert. Und außerdem gibt's praktische Apps wie Kontakte, Kalender, Notizen, Aktien und Wetter.
 
iPod touch 3.1 Softwarefunktionen.
 
Genius Mixe
Diese neue Funktion ist wie ein privater DJ, der deine iTunes Mediathek durchsucht, um Songs zu finden, die gut zusammenpassen und aus diesen dann tolle Mixe erstellt. Alles ganz automatisch.
Genius Empfehlungen für Apps
Im App Store gibt's zehntausende Apps. Wie soll man da die richtig collen neuen finden? Mit Genius. Denn Genius sieht sich die Apps an, die du schon hast, und empfiehlt dir weitere.
 
Peer-to-Peer-Spiele
Die neusten Spiele kannst du ganz leicht mit Freunden spielen - egal, ob sie neben dir oder in einer anderen Ecke des Landes sitzen.
 
Kauf Filme, Fernsehsendungen und Hörbücher via Wi-Fi
Lade via Wi-Fi Filme, Fernsehsendungen, Musikvideos und Hörbücher aus dem iTunes Store auf deinen iPod touch.
 
Tastatur im Querformat
Du brauchst mehr Platz zum Tippen? Dreh den iPod touch ins Querformat, um in Mail, Notizen und Safari mit einer größeren Tastatur zu arbeiten.
 
Cut, Copy & Paste
Einfach Text und Fotos ausschneiden, kopieren und wieder einsetzen - selbst zwischen Programmen. Du kannst auch Inhalte aus dem Web kopieren.
 
Spotlight Suche
Gesucht, gefunden - von einem Ort aus. Spotlight durchsucht alle deine Kontakte, E-Mails, Kalender und Notizen und auch alle Songs und Videos.
 
Stereo Bluetooth
Hör Musik und andere Audioinhalte drahtlos. Verbinde den iPod touch mit kompatiblen Bluetooth Stereokopfhörern.

Automatischer Wi-Fi-Login
Wenn du dich einmal bei einem Wi-Fi-Hotspot anmeldest, loggt der iPod touch sich beim nächsten Mal automatisch ein.
 
Shake to Shuffle
Schüttel den iPod kurz, und schon springt er nach dem Zufallsprinzip zu einem anderen Song in deiner Sammlung. Lass dich einfach überraschen.
 
Bedienungshilfen
Der neue iPod touch hat standardmäßig Bedienungshilfen integriert, mit denen auch Menschen mit Beeinträchtigungen alles, was der iPod touch zu bieten hat, erleben können. Alle Bedienungshilfen des iPod touch ansehen
 
Kindersicherung
Du entscheidest, welche Musik, Videos und Apps auf dem iPod touch für deine Kinder geeignet sind.
Der iPod touch hat auch die folgenden praktischen Apps:
 
Kalender
Das Programm ""Kalender"" funktioniert mit Yahoo!, Google, Microsoft Outlook, iCal, MobileMe und Microsoft Exchange ActiveSync für Unternehmen. Füge Termine hinzu, lass dich an Termine erinnern, und abonniere Kalender, damit du über Feiertage und Sportveranstaltungen auf dem Laufenden bleibst.
 
Kontakte
Namen, E-Mail-Adressen, Telefonnummern und mehr - immer zur Hand. Synchronisier Kontakte in iTunes auf dem Mac oder PC mit dem iPod touch. Neue Kontakte kannst du auch unterwegs mit einem einfachen Fingertipp hinzufügen.
 
Notizen
Schluss mit Papier und Bleistift. Mach dir mit ""Notizen"" auf dem iPod schnell eine Notiz, damit du wichtige Infos immer parat hast. Maile deine Gedanken mit der integrierten Mail-Funktion an dich oder andere.
 
Aktien
Die Aktien App auf dem iPod touch zeigt dir Börseninformationen für die Aktien, die dich interessieren. Wenn du nähere Details über eine Aktie brauchst, tipp auf ""Y!"", um im Handumdrehen Yahoo! Finance zu öffnen.
 
Wetter
Informier dich über das Wetter in der ganzen Welt oder zuhause. Füge die gewünschten Städte hinzu und zeige eine sechstägige Vorhersage für alle an. Tipp auf ""Y!"", um den Yahoo! Stadtführer zu öffnen, der dir zeigt, wo was los ist.
 
Rechner
Im Programm ""Rechner"" des iPod touch stecken gleich zwei Rechner. Im Hochformat kannst du ihn als einfachen Taschenrechner verwenden. Dreh den iPod touch ins Querformat, um aus ihm einen wissenschaftlichen Rechner zu machen.
 
iPod touch Technologie
Dank der revolutionären Hardwaretechnologie im iPod touch kannst du alle Funktionen mit Streichen, Tippen und Auf- oder Zuziehen steuern. Deswegen wirkt das Autorennen so echt. Deswegen kannst du das, was du eben im Café mitbekommen hast, sofort twittern. Und genau deswegen ist der iPod touch der beste iPod aller Zeiten.
 
Multi-Touch
Das Multi-Touch-Display besitzt einen Schutzfilm über der kapazitiven Sensorik, die Berührungen anhand elektrischer Felder erkennt. Diese Informationen werden an das darunterliegende LCD-Display übertragen. Dank der Software des iPod touch kannst du mit Cover Flow durch Alben stöbern, durch deine Fotos blättern, mit Auf- und Zuziehen Bildausschnitte von Websites zoomen und Spiele superpräzise steuern.

Beschleunigungssensor
Der iPod touch reagiert über einen integrierten Beschleunigungssensor auf Bewegungen. Dieser Sensor erkennt, wenn du deinen iPod touch ins Querformat drehst und verändert automatisch den Inhalt des Displays. Die Technologie des Beschleunigungssensors kommt besonders bei Spielen gut, denn damit bist du mitten im Spielgeschehen. Das ist perfekt für Autorennen, bei denen der ganze iPod zum Lenkrad wird, und Geschicklichkeitsspiele wie Rolando, bei denen du das Spiel mit deinen Bewegungen steuerst
 
Drahtlos
Der iPod touch hat eine integrierte Unterstützung für drahtlosen 802.11b/g Internetzugriff. Überall, wo es ein Wi-Fi-Netzwerk gibt, kommst du mit deinem iPod touch ins Internet. Im Café mailen. Am Flughafen im Web surfen. Spiele vom Sofa aus kaufen. Im iTunes Store stöbern und Musik kaufen und laden. Der iPod touch findet nahegelegene Wi-Fi-Hot-Spots, auch geschützte Netzwerke. Wenn du ein bestimmtes Netzwerk bisher noch nicht verwendet hast, Drahtlos Symbol musst du beim ersten Mal ein Kennwort eingeben, das sich der iPod touch dann merkt. Wenn du dann das nächste Mal in Reichweite dieses Netzwerks bist, loggt er sich automatisch ein.
 
Bluetooth
Bluetooth ist eine drahtlose Technologie, mit der du Geräte ohne lästige Kabel verwenden kannst. Was bedeutet das für den iPod touch? Du kannst jetzt mit dem iPod touch und Bluetooth Kopfhörern Musik hören, ganz egal, wo im Raum der iPod ist. Du kannst also auf dem Bett relaxen, während der iPod auf dem Schreibtisch aufgeladen wird. Bluetooth auf dem iPod touch eignet sich auch besonders für Peer-to-Peer-Spiele.
 
Design
Der iPod touch ist von außen genau so großartig wie von innen. Du brauchst nur einen in die Hand zu nehmen. Das Gehäuse des iPod touch ist gerade einmal 8,5 mm hoch. Das optische Glas auf der Vorderseite und die Rückseite aus poliertem Edelstahl geben ihm einen eleganten Touch und fühlen sich in der Hand einfach gut an. Schalte ihn ein und du wirst über das brillante 3,5"" Display einfach staunen. Der iPod touch ist die perfekte Kombination aus großartigem Design und revolutionärer Technologie - das perfekte Paket.
";2;False;0;;;Apple iPod Touch 64 GB schwarz mit integrierter WiFi Funktion;apple-ipod-touch-64-gb-schwarz;True;True;P-1280;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;349.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40186,8528819444;44;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000434-apple-ipod-touch-64-gb-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000435-apple-ipod-touch-64-gb-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000436-apple-ipod-touch-64-gb-schwarz.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Apple iPod shuffle 2 GB grün;Apple iPod shuffle 2 GB grün;"

Apple iPod shuffle 2GB grün
 

Wie seine größeren Geschwister besitzt auch der iPod shuffle kreisförmig angeordnete, ergonomische Bedienelemente.
Der Kopfhöreranschluss am iPod shuffle dient gleichzeitig als Dock-Anschluss. Drehen Sie den iPod shuffle auf die Seite und setzen Sie ihn in das mitgelieferte Dock ein.
Dank eines stabilen, integrierten Clips lässt sich der iPod shuffle fast überall befestigen. Klemmen Sie ihn am T-Shirt, am Hemdkragen oder am Trageriemen von Rucksack oder Handtasche fest.
Lassen Sie sich aufs Ungewisse ein: Verwenden Sie den Schalter für die Zufallswiedergabe, um den Inhalt Ihres iPod shuffle neu zu mischen.
verbesserte Kopfhörer und das neue iTunes 8.0
 
Einfach Musik anhaben mit dem Apple iPOD SHUFFLE 2GB.Tragen Sie bis zu 500 Songs am Ärmel. Oder am Gürtel. Oder am Sportoutfit. Das Erkennungszeichen für Musikfans - den Apple iPOD SHUFFLE. Füllen Sie Ihren Apple iPOD SHUFFLE silber 1GB spielend einfach. iTunes ist der Store für Unterhaltungsinhalte. Ihre super organisierte Musiksammlung und Jukebox. Und die Software, mit der Sie Ihren Apple iPOD SHUFFLE mit einem Mausklick füllen. Das farbige Gehäuse aus eloxiertem Aluminium in silber passt zum genial einfachen Design des Apple iPOD SHUFFLE.
 
Leistungseigenschaften
 
2 GB Flash-Memory Speicher
min. Audio-Datenrate: 8 KBit/s
max. Audio-Datenrate: 320 KBit/s
Frequenzgang-Untergrenze: 20 Hz
Frequenzgang-Obergrenze: 20000 Hz
 
Formate/Standards
 
MP3-Standard
AAC + MP3 Standard
WAV-Dateiformat kompatibel
Audible-Format kompatibel
AIFF-Format kompatibel
 
Bedienung
 
Musiktitel-Verwaltung
 
Leistungsaufnahme/Spannungsversorgung

Li-Polymer Akku
12 Std. Spieldauer mit Akku
Ladezeit für Akku: 4 Std.
 
Anschlüsse
 
Kopfhörer-Anschluß
USB-Schnittstelle
Anschluß für Docking-Station
 
Gehäuse-Eigenschaften
 
Breite: 4.12 cm
Höhe: 2.73 cm
Tiefe: 1.05 cm
Gewicht: 15.5 g

";2;False;0;;;Apple iPod shuffle 2 GB grün;apple-ipod-shuffle-2-gb-gruen;True;True;P-1140;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;64.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40186,8481481482;37;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000429-apple-ipod-shuffle-2-gb-grun.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000430-apple-ipod-shuffle-2-gb-grun.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000431-apple-ipod-shuffle-2-gb-grun.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Apple iPod shuffle 2 GB schwarz;Apple iPod shuffle 2 GB schwarz;"
Apple iPod shuffle 2GB schwarz
 
 
Der kleinste iPod der Welt
 
 
Um den kleinsten iPod der Welt zu bauen, haben wir die Steuerung vom iPod shuffle in das Ohrhörerkabel integriert.
So wird der iPod shuffle noch kleiner und die Steuerung ist genau da, wo du sie einfach erreichst.
Wenn du einen Song abspielen, anhalten oder überspringen möchtest,
musst du nicht lange nach dem iPod shuffle suchen - greif einfach zum Kabel und drücke auf eine der Tasten.
Dieser Entertainment-Winzling sagt Ihnen auf Knopfdruck, welchen Titel er gerade abspielt
Organisieren Sie Ihre Musik in verschiedenen Wiedergabeslisten
Dank eines stabilen, integrierten Clips lässt sich der iPod shuffle fast überall befestigen.
Lassen Sie sich aufs Ungewisse ein: Verwenden Sie den Schalter für die Zufallswiedergabe,
um den Inhalt Ihres iPod shuffle neu zu mischen.
Lieferumfang: Apple Earphones mit Remote Fernbedienung
 
iPod shuffle - In leuchtenden neuen Farben spricht Musik dich richtig an
 
Der kleinste iPod der Welt
Um den kleinsten iPod der Welt zu bauen, haben wir die Steuerung vom iPod shuffle in das Ohrhörerkabel integriert. So wird der iPod shuffle noch kleiner und die Steuerung ist genau da, wo du sie einfach erreichst. Wenn du einen Song abspielen, anhalten oder überspringen möchtest, musst du nicht lange nach dem iPod shuffle suchen - greif einfach zum Kabel und drücke auf eine der Tasten.
 
Der erste iPod, der mit dir spricht
Die VoiceOver Funktion ist mit Sicherheit der nächste Hit auf dem iPod shuffle.1 Angenommen du hörst einen Song und willst wissen, wie er heißt oder von wem er ist: Einfach Knopf drücken und VoiceOver sagt es dir. Sogar die Namen deiner Wiedergabelisten verrät es dir. Und wenn die Batterie aufgeladen werden muss, sagt VoiceOver dir das auch.
 
Leichtbedienung
Die Steuerung befindet sich am Kabel des rechten Ohrstöpsels. Dadurch, dass die Steuerung jetzt hier angebracht ist, kannst du deine Musiktitel durchsuchen - und die VoiceOver Funktion aktivieren - ohne vom Joggen, Rad fahren oder anderen Aktivitäten abgelenkt zu werden. Der iPod shuffle wird mit dieser einfachen Steuerung geliefert. Du kannst aber auch Kopfhörer mit ähnlichen Bedienelementen von Herstellern wie Scosche, Klipsch, V-MODA und Belkin verwenden.
 

Dein Musikarchiv. Für unterwegs
Der iPod shuffle kommt jetzt mit 2 GB oder 4 GB. Mit dem 4 GB Modell hast du jede Menge Platz, um Musik für viele Stunden - bis zu 1.000 Songs - zu speichern.2 Damit bist du im Fitnessstudio oder auf dem Weg zur Arbeit bestens gerüstet. Außerdem kannst du jetzt mehrere Wiedergabelisten und auch Hörbücher verwenden.
 
Mehrere Wiedergabelisten
Wahrscheinlich hast du dir in iTunes schon einige Wiedergabelisten zusammengestellt. Eine für unterwegs. Eine fürs Fitnessstudio. Eine zum Chillen. Jetzt kannst du deine Wiedergabelisten auf dem Computer mit dem iPod shuffle synchronisieren und hast immer genau den richtigen Mix - egal, was du gerade machst oder in welcher Stimmung du bist. VoiceOver nennt dir den Namen jeder Wiedergabeliste. So kannst du ganz leicht zwischen ihnen wechseln und genau die auswählen, nach der dir gerade ist.
 
Farbe bekennen
Mit dem flachen, robusten Gehäuse aus eloxiertem Aluminium ist der iPod shuffle immer das passende Accessoire. In leuchtendem Pink, Blau, Grün, Schwarz oder Silber ist er ein echtes Fashion Statement. Ganz neu dabei: der iPod shuffle Special Edition in poliertem Edelstahl (So werden Rockstars nun mal behandelt). Sogar der iPod shuffle Clip sieht stylish aus. Er klemmt sicher an Hemd, Jacke, Sportzeug oder am Rucksack. So wird der iPod shuffle zum perfekten Fashtech-Accessoire. Und klar, natürlich ist noch Platz für eine persönliche Gravur.

Mehrsprachig
Ein französisches Chanson. Ein spanischer Bolero. Eine italienische Arie. Dein Musikarchiv enthält Musik aus allen Ländern der Welt. Deshalb spricht VoiceOver 20 Sprachen und kann die Namen von Songs und Interpreten mit der richtigen Aussprache sprechen.
 
Zufall oder kein Zufall?
Der Schalter am iPod shuffle hat drei Einstellungen. Links wird deine Musik zufällig durcheinander gewürfelt. In der Mitte werden deine Songs in der normalen Reihenfolge gespielt. Rechts wird der iPod shuffle ausgeschaltet.
";2;False;0;;;Apple iPod shuffle Tragbarer MP3-Player 4 GB 3. Generation;apple-ipod-shuffle-2-gb-schwarz;True;True;P-1200;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;61.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40186,8421875;39;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000585-apple-ipod-shuffle-4-gb-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000586-apple-ipod-shuffle-4-gb-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000587-apple-ipod-shuffle-4-gb-schwarz.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Apple iPod shuffle 2 GB pink;Apple iPod shuffle 2 GB pink;"

Apple iPod shuffle 2 GB pink 

Der kleinste iPod der Welt
 
 
Um den kleinsten iPod der Welt zu bauen, haben wir die Steuerung vom iPod shuffle in das Ohrhörerkabel integriert.
So wird der iPod shuffle noch kleiner und die Steuerung ist genau da, wo du sie einfach erreichst.
Wenn du einen Song abspielen, anhalten oder überspringen möchtest,
musst du nicht lange nach dem iPod shuffle suchen - greif einfach zum Kabel und drücke auf eine der Tasten.
Dieser Entertainment-Winzling sagt Ihnen auf Knopfdruck, welchen Titel er gerade abspielt
Organisieren Sie Ihre Musik in verschiedenen Wiedergabeslisten
Dank eines stabilen, integrierten Clips lässt sich der iPod shuffle fast überall befestigen.
Lassen Sie sich aufs Ungewisse ein: Verwenden Sie den Schalter für die Zufallswiedergabe,
um den Inhalt Ihres iPod shuffle neu zu mischen.
Lieferumfang: Apple Earphones mit Remote Fernbedienung
 
iPod shuffle - In leuchtenden neuen Farben spricht Musik dich richtig an
 
Der kleinste iPod der Welt
Um den kleinsten iPod der Welt zu bauen, haben wir die Steuerung vom iPod shuffle in das Ohrhörerkabel integriert. So wird der iPod shuffle noch kleiner und die Steuerung ist genau da, wo du sie einfach erreichst. Wenn du einen Song abspielen, anhalten oder überspringen möchtest, musst du nicht lange nach dem iPod shuffle suchen - greif einfach zum Kabel und drücke auf eine der Tasten.
 
Der erste iPod, der mit dir spricht
Die VoiceOver Funktion ist mit Sicherheit der nächste Hit auf dem iPod shuffle.1 Angenommen du hörst einen Song und willst wissen, wie er heißt oder von wem er ist: Einfach Knopf drücken und VoiceOver sagt es dir. Sogar die Namen deiner Wiedergabelisten verrät es dir. Und wenn die Batterie aufgeladen werden muss, sagt VoiceOver dir das auch.
 
Leichtbedienung
Die Steuerung befindet sich am Kabel des rechten Ohrstöpsels. Dadurch, dass die Steuerung jetzt hier angebracht ist, kannst du deine Musiktitel durchsuchen - und die VoiceOver Funktion aktivieren - ohne vom Joggen, Rad fahren oder anderen Aktivitäten abgelenkt zu werden. Der iPod shuffle wird mit dieser einfachen Steuerung geliefert. Du kannst aber auch Kopfhörer mit ähnlichen Bedienelementen von Herstellern wie Scosche, Klipsch, V-MODA und Belkin verwenden.
 

Dein Musikarchiv. Für unterwegs
Der iPod shuffle kommt jetzt mit 2 GB oder 4 GB. Mit dem 4 GB Modell hast du jede Menge Platz, um Musik für viele Stunden - bis zu 1.000 Songs - zu speichern.2 Damit bist du im Fitnessstudio oder auf dem Weg zur Arbeit bestens gerüstet. Außerdem kannst du jetzt mehrere Wiedergabelisten und auch Hörbücher verwenden.
 
Mehrere Wiedergabelisten
Wahrscheinlich hast du dir in iTunes schon einige Wiedergabelisten zusammengestellt. Eine für unterwegs. Eine fürs Fitnessstudio. Eine zum Chillen. Jetzt kannst du deine Wiedergabelisten auf dem Computer mit dem iPod shuffle synchronisieren und hast immer genau den richtigen Mix - egal, was du gerade machst oder in welcher Stimmung du bist. VoiceOver nennt dir den Namen jeder Wiedergabeliste. So kannst du ganz leicht zwischen ihnen wechseln und genau die auswählen, nach der dir gerade ist.
 
Farbe bekennen
Mit dem flachen, robusten Gehäuse aus eloxiertem Aluminium ist der iPod shuffle immer das passende Accessoire. In leuchtendem Pink, Blau, Grün, Schwarz oder Silber ist er ein echtes Fashion Statement. Ganz neu dabei: der iPod shuffle Special Edition in poliertem Edelstahl (So werden Rockstars nun mal behandelt). Sogar der iPod shuffle Clip sieht stylish aus. Er klemmt sicher an Hemd, Jacke, Sportzeug oder am Rucksack. So wird der iPod shuffle zum perfekten Fashtech-Accessoire. Und klar, natürlich ist noch Platz für eine persönliche Gravur.

Mehrsprachig
Ein französisches Chanson. Ein spanischer Bolero. Eine italienische Arie. Dein Musikarchiv enthält Musik aus allen Ländern der Welt. Deshalb spricht VoiceOver 20 Sprachen und kann die Namen von Songs und Interpreten mit der richtigen Aussprache sprechen.
 
Zufall oder kein Zufall?
Der Schalter am iPod shuffle hat drei Einstellungen. Links wird deine Musik zufällig durcheinander gewürfelt. In der Mitte werden deine Songs in der normalen Reihenfolge gespielt. Rechts wird der iPod shuffle ausgeschaltet.
";2;False;0;;;Apple iPod shuffle 1GB;apple-ipod-shuffle-2-gb-pink-2;True;True;P-1190;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;59.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40186,8385648148;39;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000588-apple-ipod-shuffle-2-gb-pink.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000579-apple-ipod-shuffle-4-gb-blau.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000580-apple-ipod-shuffle-4-gb-blau.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Apple iPod shuffle 2 GB blau;Apple iPod shuffle 2 GB blau;"
Apple iPod shuffle 2GB blau
 
 
Der kleinste iPod der Welt
 
 
Um den kleinsten iPod der Welt zu bauen, haben wir die Steuerung vom iPod shuffle in das Ohrhörerkabel integriert.
So wird der iPod shuffle noch kleiner und die Steuerung ist genau da, wo du sie einfach erreichst.
Wenn du einen Song abspielen, anhalten oder überspringen möchtest,
musst du nicht lange nach dem iPod shuffle suchen - greif einfach zum Kabel und drücke auf eine der Tasten.
Dieser Entertainment-Winzling sagt Ihnen auf Knopfdruck, welchen Titel er gerade abspielt
Organisieren Sie Ihre Musik in verschiedenen Wiedergabeslisten
Dank eines stabilen, integrierten Clips lässt sich der iPod shuffle fast überall befestigen.
Lassen Sie sich aufs Ungewisse ein: Verwenden Sie den Schalter für die Zufallswiedergabe,
um den Inhalt Ihres iPod shuffle neu zu mischen.
Lieferumfang: Apple Earphones mit Remote Fernbedienung
 
iPod shuffle - In leuchtenden neuen Farben spricht Musik dich richtig an
 
Der kleinste iPod der Welt
Um den kleinsten iPod der Welt zu bauen, haben wir die Steuerung vom iPod shuffle in das Ohrhörerkabel integriert. So wird der iPod shuffle noch kleiner und die Steuerung ist genau da, wo du sie einfach erreichst. Wenn du einen Song abspielen, anhalten oder überspringen möchtest, musst du nicht lange nach dem iPod shuffle suchen - greif einfach zum Kabel und drücke auf eine der Tasten.
 
Der erste iPod, der mit dir spricht
Die VoiceOver Funktion ist mit Sicherheit der nächste Hit auf dem iPod shuffle.1 Angenommen du hörst einen Song und willst wissen, wie er heißt oder von wem er ist: Einfach Knopf drücken und VoiceOver sagt es dir. Sogar die Namen deiner Wiedergabelisten verrät es dir. Und wenn die Batterie aufgeladen werden muss, sagt VoiceOver dir das auch.
 
Leichtbedienung
Die Steuerung befindet sich am Kabel des rechten Ohrstöpsels. Dadurch, dass die Steuerung jetzt hier angebracht ist, kannst du deine Musiktitel durchsuchen - und die VoiceOver Funktion aktivieren - ohne vom Joggen, Rad fahren oder anderen Aktivitäten abgelenkt zu werden. Der iPod shuffle wird mit dieser einfachen Steuerung geliefert. Du kannst aber auch Kopfhörer mit ähnlichen Bedienelementen von Herstellern wie Scosche, Klipsch, V-MODA und Belkin verwenden.
 

Dein Musikarchiv. Für unterwegs
Der iPod shuffle kommt jetzt mit 2 GB oder 4 GB. Mit dem 4 GB Modell hast du jede Menge Platz, um Musik für viele Stunden - bis zu 1.000 Songs - zu speichern.2 Damit bist du im Fitnessstudio oder auf dem Weg zur Arbeit bestens gerüstet. Außerdem kannst du jetzt mehrere Wiedergabelisten und auch Hörbücher verwenden.
 
Mehrere Wiedergabelisten
Wahrscheinlich hast du dir in iTunes schon einige Wiedergabelisten zusammengestellt. Eine für unterwegs. Eine fürs Fitnessstudio. Eine zum Chillen. Jetzt kannst du deine Wiedergabelisten auf dem Computer mit dem iPod shuffle synchronisieren und hast immer genau den richtigen Mix - egal, was du gerade machst oder in welcher Stimmung du bist. VoiceOver nennt dir den Namen jeder Wiedergabeliste. So kannst du ganz leicht zwischen ihnen wechseln und genau die auswählen, nach der dir gerade ist.
 
Farbe bekennen
Mit dem flachen, robusten Gehäuse aus eloxiertem Aluminium ist der iPod shuffle immer das passende Accessoire. In leuchtendem Pink, Blau, Grün, Schwarz oder Silber ist er ein echtes Fashion Statement. Ganz neu dabei: der iPod shuffle Special Edition in poliertem Edelstahl (So werden Rockstars nun mal behandelt). Sogar der iPod shuffle Clip sieht stylish aus. Er klemmt sicher an Hemd, Jacke, Sportzeug oder am Rucksack. So wird der iPod shuffle zum perfekten Fashtech-Accessoire. Und klar, natürlich ist noch Platz für eine persönliche Gravur.

Mehrsprachig
Ein französisches Chanson. Ein spanischer Bolero. Eine italienische Arie. Dein Musikarchiv enthält Musik aus allen Ländern der Welt. Deshalb spricht VoiceOver 20 Sprachen und kann die Namen von Songs und Interpreten mit der richtigen Aussprache sprechen.
 
Zufall oder kein Zufall?
Der Schalter am iPod shuffle hat drei Einstellungen. Links wird deine Musik zufällig durcheinander gewürfelt. In der Mitte werden deine Songs in der normalen Reihenfolge gespielt. Rechts wird der iPod shuffle ausgeschaltet.
";2;False;0;;;Apple iPod shuffle Tragbarer MP3-Player 4 GB 3. Generation;apple-ipod-shuffle-2-gb-blau-2;True;True;P-1180;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;59.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40186,8361921296;39;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000578-apple-ipod-shuffle-4-gb-blau.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000579-apple-ipod-shuffle-4-gb-blau.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000580-apple-ipod-shuffle-4-gb-blau.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Apple iPod shuffle 2 GB grün;Apple iPod shuffle 2 GB grün;"
Apple iPod shuffle 2GB grün
 
 
Der kleinste iPod der Welt
 
 
Um den kleinsten iPod der Welt zu bauen, haben wir die Steuerung vom iPod shuffle in das Ohrhörerkabel integriert.
So wird der iPod shuffle noch kleiner und die Steuerung ist genau da, wo du sie einfach erreichst.
Wenn du einen Song abspielen, anhalten oder überspringen möchtest,
musst du nicht lange nach dem iPod shuffle suchen - greif einfach zum Kabel und drücke auf eine der Tasten.
Dieser Entertainment-Winzling sagt Ihnen auf Knopfdruck, welchen Titel er gerade abspielt
Organisieren Sie Ihre Musik in verschiedenen Wiedergabeslisten
Dank eines stabilen, integrierten Clips lässt sich der iPod shuffle fast überall befestigen.
Lassen Sie sich aufs Ungewisse ein: Verwenden Sie den Schalter für die Zufallswiedergabe,
um den Inhalt Ihres iPod shuffle neu zu mischen.
Lieferumfang: Apple Earphones mit Remote Fernbedienung
 
iPod shuffle - In leuchtenden neuen Farben spricht Musik dich richtig an
 
Der kleinste iPod der Welt
Um den kleinsten iPod der Welt zu bauen, haben wir die Steuerung vom iPod shuffle in das Ohrhörerkabel integriert. So wird der iPod shuffle noch kleiner und die Steuerung ist genau da, wo du sie einfach erreichst. Wenn du einen Song abspielen, anhalten oder überspringen möchtest, musst du nicht lange nach dem iPod shuffle suchen - greif einfach zum Kabel und drücke auf eine der Tasten.
 
Der erste iPod, der mit dir spricht
Die VoiceOver Funktion ist mit Sicherheit der nächste Hit auf dem iPod shuffle.1 Angenommen du hörst einen Song und willst wissen, wie er heißt oder von wem er ist: Einfach Knopf drücken und VoiceOver sagt es dir. Sogar die Namen deiner Wiedergabelisten verrät es dir. Und wenn die Batterie aufgeladen werden muss, sagt VoiceOver dir das auch.
 
Leichtbedienung
Die Steuerung befindet sich am Kabel des rechten Ohrstöpsels. Dadurch, dass die Steuerung jetzt hier angebracht ist, kannst du deine Musiktitel durchsuchen - und die VoiceOver Funktion aktivieren - ohne vom Joggen, Rad fahren oder anderen Aktivitäten abgelenkt zu werden. Der iPod shuffle wird mit dieser einfachen Steuerung geliefert. Du kannst aber auch Kopfhörer mit ähnlichen Bedienelementen von Herstellern wie Scosche, Klipsch, V-MODA und Belkin verwenden.
 

Dein Musikarchiv. Für unterwegs
Der iPod shuffle kommt jetzt mit 2 GB oder 4 GB. Mit dem 4 GB Modell hast du jede Menge Platz, um Musik für viele Stunden - bis zu 1.000 Songs - zu speichern.2 Damit bist du im Fitnessstudio oder auf dem Weg zur Arbeit bestens gerüstet. Außerdem kannst du jetzt mehrere Wiedergabelisten und auch Hörbücher verwenden.
 
Mehrere Wiedergabelisten
Wahrscheinlich hast du dir in iTunes schon einige Wiedergabelisten zusammengestellt. Eine für unterwegs. Eine fürs Fitnessstudio. Eine zum Chillen. Jetzt kannst du deine Wiedergabelisten auf dem Computer mit dem iPod shuffle synchronisieren und hast immer genau den richtigen Mix - egal, was du gerade machst oder in welcher Stimmung du bist. VoiceOver nennt dir den Namen jeder Wiedergabeliste. So kannst du ganz leicht zwischen ihnen wechseln und genau die auswählen, nach der dir gerade ist.
 
Farbe bekennen
Mit dem flachen, robusten Gehäuse aus eloxiertem Aluminium ist der iPod shuffle immer das passende Accessoire. In leuchtendem Pink, Blau, Grün, Schwarz oder Silber ist er ein echtes Fashion Statement. Ganz neu dabei: der iPod shuffle Special Edition in poliertem Edelstahl (So werden Rockstars nun mal behandelt). Sogar der iPod shuffle Clip sieht stylish aus. Er klemmt sicher an Hemd, Jacke, Sportzeug oder am Rucksack. So wird der iPod shuffle zum perfekten Fashtech-Accessoire. Und klar, natürlich ist noch Platz für eine persönliche Gravur.

Mehrsprachig
Ein französisches Chanson. Ein spanischer Bolero. Eine italienische Arie. Dein Musikarchiv enthält Musik aus allen Ländern der Welt. Deshalb spricht VoiceOver 20 Sprachen und kann die Namen von Songs und Interpreten mit der richtigen Aussprache sprechen.
 
Zufall oder kein Zufall?
Der Schalter am iPod shuffle hat drei Einstellungen. Links wird deine Musik zufällig durcheinander gewürfelt. In der Mitte werden deine Songs in der normalen Reihenfolge gespielt. Rechts wird der iPod shuffle ausgeschaltet.
";2;False;0;;;Apple iPod shuffle Tragbarer MP3-Player 4 GB 3. Generation;apple-ipod-shuffle-2-gb-gruen-2;True;True;P-1170;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;59.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40186,8328587963;39;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000584-apple-ipod-shuffle-4-gb-grun.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000579-apple-ipod-shuffle-4-gb-blau.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000580-apple-ipod-shuffle-4-gb-blau.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Apple iPod shuffle 2 GB silber;Apple iPod shuffle 2 GB silber;"
Apple iPod shuffle 2GB silber  
 
Der kleinste iPod der Welt
 
 
Um den kleinsten iPod der Welt zu bauen, haben wir die Steuerung vom iPod shuffle in das Ohrhörerkabel integriert.
So wird der iPod shuffle noch kleiner und die Steuerung ist genau da, wo du sie einfach erreichst.
Wenn du einen Song abspielen, anhalten oder überspringen möchtest,
musst du nicht lange nach dem iPod shuffle suchen - greif einfach zum Kabel und drücke auf eine der Tasten.
Dieser Entertainment-Winzling sagt Ihnen auf Knopfdruck, welchen Titel er gerade abspielt
Organisieren Sie Ihre Musik in verschiedenen Wiedergabeslisten
Dank eines stabilen, integrierten Clips lässt sich der iPod shuffle fast überall befestigen.
Lassen Sie sich aufs Ungewisse ein: Verwenden Sie den Schalter für die Zufallswiedergabe,
um den Inhalt Ihres iPod shuffle neu zu mischen.
Lieferumfang: Apple Earphones mit Remote Fernbedienung
 
iPod shuffle - In leuchtenden neuen Farben spricht Musik dich richtig an
 
Der kleinste iPod der Welt
Um den kleinsten iPod der Welt zu bauen, haben wir die Steuerung vom iPod shuffle in das Ohrhörerkabel integriert. So wird der iPod shuffle noch kleiner und die Steuerung ist genau da, wo du sie einfach erreichst. Wenn du einen Song abspielen, anhalten oder überspringen möchtest, musst du nicht lange nach dem iPod shuffle suchen - greif einfach zum Kabel und drücke auf eine der Tasten.
 
Der erste iPod, der mit dir spricht
Die VoiceOver Funktion ist mit Sicherheit der nächste Hit auf dem iPod shuffle.1 Angenommen du hörst einen Song und willst wissen, wie er heißt oder von wem er ist: Einfach Knopf drücken und VoiceOver sagt es dir. Sogar die Namen deiner Wiedergabelisten verrät es dir. Und wenn die Batterie aufgeladen werden muss, sagt VoiceOver dir das auch.
 
Leichtbedienung
Die Steuerung befindet sich am Kabel des rechten Ohrstöpsels. Dadurch, dass die Steuerung jetzt hier angebracht ist, kannst du deine Musiktitel durchsuchen - und die VoiceOver Funktion aktivieren - ohne vom Joggen, Rad fahren oder anderen Aktivitäten abgelenkt zu werden. Der iPod shuffle wird mit dieser einfachen Steuerung geliefert. Du kannst aber auch Kopfhörer mit ähnlichen Bedienelementen von Herstellern wie Scosche, Klipsch, V-MODA und Belkin verwenden.
 

Dein Musikarchiv. Für unterwegs
Der iPod shuffle kommt jetzt mit 2 GB oder 4 GB. Mit dem 4 GB Modell hast du jede Menge Platz, um Musik für viele Stunden - bis zu 1.000 Songs - zu speichern.2 Damit bist du im Fitnessstudio oder auf dem Weg zur Arbeit bestens gerüstet. Außerdem kannst du jetzt mehrere Wiedergabelisten und auch Hörbücher verwenden.
 
Mehrere Wiedergabelisten
Wahrscheinlich hast du dir in iTunes schon einige Wiedergabelisten zusammengestellt. Eine für unterwegs. Eine fürs Fitnessstudio. Eine zum Chillen. Jetzt kannst du deine Wiedergabelisten auf dem Computer mit dem iPod shuffle synchronisieren und hast immer genau den richtigen Mix - egal, was du gerade machst oder in welcher Stimmung du bist. VoiceOver nennt dir den Namen jeder Wiedergabeliste. So kannst du ganz leicht zwischen ihnen wechseln und genau die auswählen, nach der dir gerade ist.
 
Farbe bekennen
Mit dem flachen, robusten Gehäuse aus eloxiertem Aluminium ist der iPod shuffle immer das passende Accessoire. In leuchtendem Pink, Blau, Grün, Schwarz oder Silber ist er ein echtes Fashion Statement. Ganz neu dabei: der iPod shuffle Special Edition in poliertem Edelstahl (So werden Rockstars nun mal behandelt). Sogar der iPod shuffle Clip sieht stylish aus. Er klemmt sicher an Hemd, Jacke, Sportzeug oder am Rucksack. So wird der iPod shuffle zum perfekten Fashtech-Accessoire. Und klar, natürlich ist noch Platz für eine persönliche Gravur.

Mehrsprachig
Ein französisches Chanson. Ein spanischer Bolero. Eine italienische Arie. Dein Musikarchiv enthält Musik aus allen Ländern der Welt. Deshalb spricht VoiceOver 20 Sprachen und kann die Namen von Songs und Interpreten mit der richtigen Aussprache sprechen.
 
Zufall oder kein Zufall?
Der Schalter am iPod shuffle hat drei Einstellungen. Links wird deine Musik zufällig durcheinander gewürfelt. In der Mitte werden deine Songs in der normalen Reihenfolge gespielt. Rechts wird der iPod shuffle ausgeschaltet.
";2;False;0;;;Apple iPod shuffle Tragbarer MP3-Player 4 GB 3. Generation;apple-ipod-shuffle-2-gb-silber;True;True;P-1160;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;61.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40186,8309259259;39;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000220-apple-ipod-shuffle-4-gb-silber.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000221-apple-ipod-shuffle-4-gb-silber.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000222-apple-ipod-shuffle-4-gb-silber.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Apple iPod shuffle 4 GB schwarz;Apple iPod shuffle 4 GB schwarz;"
Apple iPod shuffle 4GB schwarz
 
 
Der kleinste iPod der Welt
 
 
Um den kleinsten iPod der Welt zu bauen, haben wir die Steuerung vom iPod shuffle in das Ohrhörerkabel integriert.
So wird der iPod shuffle noch kleiner und die Steuerung ist genau da, wo du sie einfach erreichst.
Wenn du einen Song abspielen, anhalten oder überspringen möchtest,
musst du nicht lange nach dem iPod shuffle suchen - greif einfach zum Kabel und drücke auf eine der Tasten.
Dieser Entertainment-Winzling sagt Ihnen auf Knopfdruck, welchen Titel er gerade abspielt
Organisieren Sie Ihre Musik in verschiedenen Wiedergabeslisten
Dank eines stabilen, integrierten Clips lässt sich der iPod shuffle fast überall befestigen.
Lassen Sie sich aufs Ungewisse ein: Verwenden Sie den Schalter für die Zufallswiedergabe,
um den Inhalt Ihres iPod shuffle neu zu mischen.
Lieferumfang: Apple Earphones mit Remote Fernbedienung
 
iPod shuffle - In leuchtenden neuen Farben spricht Musik dich richtig an
 
Der kleinste iPod der Welt
Um den kleinsten iPod der Welt zu bauen, haben wir die Steuerung vom iPod shuffle in das Ohrhörerkabel integriert. So wird der iPod shuffle noch kleiner und die Steuerung ist genau da, wo du sie einfach erreichst. Wenn du einen Song abspielen, anhalten oder überspringen möchtest, musst du nicht lange nach dem iPod shuffle suchen - greif einfach zum Kabel und drücke auf eine der Tasten.
 
Der erste iPod, der mit dir spricht
Die VoiceOver Funktion ist mit Sicherheit der nächste Hit auf dem iPod shuffle.1 Angenommen du hörst einen Song und willst wissen, wie er heißt oder von wem er ist: Einfach Knopf drücken und VoiceOver sagt es dir. Sogar die Namen deiner Wiedergabelisten verrät es dir. Und wenn die Batterie aufgeladen werden muss, sagt VoiceOver dir das auch.
 
Leichtbedienung
Die Steuerung befindet sich am Kabel des rechten Ohrstöpsels. Dadurch, dass die Steuerung jetzt hier angebracht ist, kannst du deine Musiktitel durchsuchen - und die VoiceOver Funktion aktivieren - ohne vom Joggen, Rad fahren oder anderen Aktivitäten abgelenkt zu werden. Der iPod shuffle wird mit dieser einfachen Steuerung geliefert. Du kannst aber auch Kopfhörer mit ähnlichen Bedienelementen von Herstellern wie Scosche, Klipsch, V-MODA und Belkin verwenden.
 

Dein Musikarchiv. Für unterwegs
Der iPod shuffle kommt jetzt mit 2 GB oder 4 GB. Mit dem 4 GB Modell hast du jede Menge Platz, um Musik für viele Stunden - bis zu 1.000 Songs - zu speichern.2 Damit bist du im Fitnessstudio oder auf dem Weg zur Arbeit bestens gerüstet. Außerdem kannst du jetzt mehrere Wiedergabelisten und auch Hörbücher verwenden.
 
Mehrere Wiedergabelisten
Wahrscheinlich hast du dir in iTunes schon einige Wiedergabelisten zusammengestellt. Eine für unterwegs. Eine fürs Fitnessstudio. Eine zum Chillen. Jetzt kannst du deine Wiedergabelisten auf dem Computer mit dem iPod shuffle synchronisieren und hast immer genau den richtigen Mix - egal, was du gerade machst oder in welcher Stimmung du bist. VoiceOver nennt dir den Namen jeder Wiedergabeliste. So kannst du ganz leicht zwischen ihnen wechseln und genau die auswählen, nach der dir gerade ist.
 
Farbe bekennen
Mit dem flachen, robusten Gehäuse aus eloxiertem Aluminium ist der iPod shuffle immer das passende Accessoire. In leuchtendem Pink, Blau, Grün, Schwarz oder Silber ist er ein echtes Fashion Statement. Ganz neu dabei: der iPod shuffle Special Edition in poliertem Edelstahl (So werden Rockstars nun mal behandelt). Sogar der iPod shuffle Clip sieht stylish aus. Er klemmt sicher an Hemd, Jacke, Sportzeug oder am Rucksack. So wird der iPod shuffle zum perfekten Fashtech-Accessoire. Und klar, natürlich ist noch Platz für eine persönliche Gravur.

Mehrsprachig
Ein französisches Chanson. Ein spanischer Bolero. Eine italienische Arie. Dein Musikarchiv enthält Musik aus allen Ländern der Welt. Deshalb spricht VoiceOver 20 Sprachen und kann die Namen von Songs und Interpreten mit der richtigen Aussprache sprechen.
 
Zufall oder kein Zufall?
Der Schalter am iPod shuffle hat drei Einstellungen. Links wird deine Musik zufällig durcheinander gewürfelt. In der Mitte werden deine Songs in der normalen Reihenfolge gespielt. Rechts wird der iPod shuffle ausgeschaltet.
";2;False;0;;;Apple iPod shuffle Tragbarer MP3-Player 4 GB 3. Generation;apple-ipod-shuffle-4-gb-schwarz;True;True;P-1240;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;79.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40186,8276273148;40;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000585-apple-ipod-shuffle-4-gb-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000586-apple-ipod-shuffle-4-gb-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000587-apple-ipod-shuffle-4-gb-schwarz.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Apple iPod shuffle 4 GB grün;Apple iPod shuffle 4 GB grün;"
Apple iPod shuffle 4GB grün
 
 
Der kleinste iPod der Welt
 
 
Um den kleinsten iPod der Welt zu bauen, haben wir die Steuerung vom iPod shuffle in das Ohrhörerkabel integriert.
So wird der iPod shuffle noch kleiner und die Steuerung ist genau da, wo du sie einfach erreichst.
Wenn du einen Song abspielen, anhalten oder überspringen möchtest,
musst du nicht lange nach dem iPod shuffle suchen - greif einfach zum Kabel und drücke auf eine der Tasten.
Dieser Entertainment-Winzling sagt Ihnen auf Knopfdruck, welchen Titel er gerade abspielt
Organisieren Sie Ihre Musik in verschiedenen Wiedergabeslisten
Dank eines stabilen, integrierten Clips lässt sich der iPod shuffle fast überall befestigen.
Lassen Sie sich aufs Ungewisse ein: Verwenden Sie den Schalter für die Zufallswiedergabe,
um den Inhalt Ihres iPod shuffle neu zu mischen.
Lieferumfang: Apple Earphones mit Remote Fernbedienung
 
iPod shuffle - In leuchtenden neuen Farben spricht Musik dich richtig an
 
Der kleinste iPod der Welt
Um den kleinsten iPod der Welt zu bauen, haben wir die Steuerung vom iPod shuffle in das Ohrhörerkabel integriert. So wird der iPod shuffle noch kleiner und die Steuerung ist genau da, wo du sie einfach erreichst. Wenn du einen Song abspielen, anhalten oder überspringen möchtest, musst du nicht lange nach dem iPod shuffle suchen - greif einfach zum Kabel und drücke auf eine der Tasten.
 
Der erste iPod, der mit dir spricht
Die VoiceOver Funktion ist mit Sicherheit der nächste Hit auf dem iPod shuffle.1 Angenommen du hörst einen Song und willst wissen, wie er heißt oder von wem er ist: Einfach Knopf drücken und VoiceOver sagt es dir. Sogar die Namen deiner Wiedergabelisten verrät es dir. Und wenn die Batterie aufgeladen werden muss, sagt VoiceOver dir das auch.
 
Leichtbedienung
Die Steuerung befindet sich am Kabel des rechten Ohrstöpsels. Dadurch, dass die Steuerung jetzt hier angebracht ist, kannst du deine Musiktitel durchsuchen - und die VoiceOver Funktion aktivieren - ohne vom Joggen, Rad fahren oder anderen Aktivitäten abgelenkt zu werden. Der iPod shuffle wird mit dieser einfachen Steuerung geliefert. Du kannst aber auch Kopfhörer mit ähnlichen Bedienelementen von Herstellern wie Scosche, Klipsch, V-MODA und Belkin verwenden.
 

Dein Musikarchiv. Für unterwegs
Der iPod shuffle kommt jetzt mit 2 GB oder 4 GB. Mit dem 4 GB Modell hast du jede Menge Platz, um Musik für viele Stunden - bis zu 1.000 Songs - zu speichern.2 Damit bist du im Fitnessstudio oder auf dem Weg zur Arbeit bestens gerüstet. Außerdem kannst du jetzt mehrere Wiedergabelisten und auch Hörbücher verwenden.
 
Mehrere Wiedergabelisten
Wahrscheinlich hast du dir in iTunes schon einige Wiedergabelisten zusammengestellt. Eine für unterwegs. Eine fürs Fitnessstudio. Eine zum Chillen. Jetzt kannst du deine Wiedergabelisten auf dem Computer mit dem iPod shuffle synchronisieren und hast immer genau den richtigen Mix - egal, was du gerade machst oder in welcher Stimmung du bist. VoiceOver nennt dir den Namen jeder Wiedergabeliste. So kannst du ganz leicht zwischen ihnen wechseln und genau die auswählen, nach der dir gerade ist.
 
Farbe bekennen
Mit dem flachen, robusten Gehäuse aus eloxiertem Aluminium ist der iPod shuffle immer das passende Accessoire. In leuchtendem Pink, Blau, Grün, Schwarz oder Silber ist er ein echtes Fashion Statement. Ganz neu dabei: der iPod shuffle Special Edition in poliertem Edelstahl (So werden Rockstars nun mal behandelt). Sogar der iPod shuffle Clip sieht stylish aus. Er klemmt sicher an Hemd, Jacke, Sportzeug oder am Rucksack. So wird der iPod shuffle zum perfekten Fashtech-Accessoire. Und klar, natürlich ist noch Platz für eine persönliche Gravur.

Mehrsprachig
Ein französisches Chanson. Ein spanischer Bolero. Eine italienische Arie. Dein Musikarchiv enthält Musik aus allen Ländern der Welt. Deshalb spricht VoiceOver 20 Sprachen und kann die Namen von Songs und Interpreten mit der richtigen Aussprache sprechen.
 
Zufall oder kein Zufall?
Der Schalter am iPod shuffle hat drei Einstellungen. Links wird deine Musik zufällig durcheinander gewürfelt. In der Mitte werden deine Songs in der normalen Reihenfolge gespielt. Rechts wird der iPod shuffle ausgeschaltet.
 
";2;False;0;;;Apple iPod shuffle Tragbarer MP3-Player 4 GB 3. Generation;apple-ipod-shuffle-4-gb-gruen;True;True;P-1230;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;77.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40186,8252662037;40;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000584-apple-ipod-shuffle-4-gb-grun.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000579-apple-ipod-shuffle-4-gb-blau.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000580-apple-ipod-shuffle-4-gb-blau.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Apple iPod shuffle 4 GB blau;Apple iPod shuffle 4GB blau;"
Apple iPod shuffle 4GB blau
 
 
Der kleinste iPod der Welt
 
 
Um den kleinsten iPod der Welt zu bauen, haben wir die Steuerung vom iPod shuffle in das Ohrhörerkabel integriert.
So wird der iPod shuffle noch kleiner und die Steuerung ist genau da, wo du sie einfach erreichst.
Wenn du einen Song abspielen, anhalten oder überspringen möchtest,
musst du nicht lange nach dem iPod shuffle suchen - greif einfach zum Kabel und drücke auf eine der Tasten.
Dieser Entertainment-Winzling sagt Ihnen auf Knopfdruck, welchen Titel er gerade abspielt
Organisieren Sie Ihre Musik in verschiedenen Wiedergabeslisten
Dank eines stabilen, integrierten Clips lässt sich der iPod shuffle fast überall befestigen.
Lassen Sie sich aufs Ungewisse ein: Verwenden Sie den Schalter für die Zufallswiedergabe,
um den Inhalt Ihres iPod shuffle neu zu mischen.
Lieferumfang: Apple Earphones mit Remote Fernbedienung
 
iPod shuffle - In leuchtenden neuen Farben spricht Musik dich richtig an
 
Der kleinste iPod der Welt
Um den kleinsten iPod der Welt zu bauen, haben wir die Steuerung vom iPod shuffle in das Ohrhörerkabel integriert. So wird der iPod shuffle noch kleiner und die Steuerung ist genau da, wo du sie einfach erreichst. Wenn du einen Song abspielen, anhalten oder überspringen möchtest, musst du nicht lange nach dem iPod shuffle suchen - greif einfach zum Kabel und drücke auf eine der Tasten.
 
Der erste iPod, der mit dir spricht
Die VoiceOver Funktion ist mit Sicherheit der nächste Hit auf dem iPod shuffle.1 Angenommen du hörst einen Song und willst wissen, wie er heißt oder von wem er ist: Einfach Knopf drücken und VoiceOver sagt es dir. Sogar die Namen deiner Wiedergabelisten verrät es dir. Und wenn die Batterie aufgeladen werden muss, sagt VoiceOver dir das auch.
 
Leichtbedienung
Die Steuerung befindet sich am Kabel des rechten Ohrstöpsels. Dadurch, dass die Steuerung jetzt hier angebracht ist, kannst du deine Musiktitel durchsuchen - und die VoiceOver Funktion aktivieren - ohne vom Joggen, Rad fahren oder anderen Aktivitäten abgelenkt zu werden. Der iPod shuffle wird mit dieser einfachen Steuerung geliefert. Du kannst aber auch Kopfhörer mit ähnlichen Bedienelementen von Herstellern wie Scosche, Klipsch, V-MODA und Belkin verwenden.
 

Dein Musikarchiv. Für unterwegs
Der iPod shuffle kommt jetzt mit 2 GB oder 4 GB. Mit dem 4 GB Modell hast du jede Menge Platz, um Musik für viele Stunden - bis zu 1.000 Songs - zu speichern.2 Damit bist du im Fitnessstudio oder auf dem Weg zur Arbeit bestens gerüstet. Außerdem kannst du jetzt mehrere Wiedergabelisten und auch Hörbücher verwenden.
 
Mehrere Wiedergabelisten
Wahrscheinlich hast du dir in iTunes schon einige Wiedergabelisten zusammengestellt. Eine für unterwegs. Eine fürs Fitnessstudio. Eine zum Chillen. Jetzt kannst du deine Wiedergabelisten auf dem Computer mit dem iPod shuffle synchronisieren und hast immer genau den richtigen Mix - egal, was du gerade machst oder in welcher Stimmung du bist. VoiceOver nennt dir den Namen jeder Wiedergabeliste. So kannst du ganz leicht zwischen ihnen wechseln und genau die auswählen, nach der dir gerade ist.
 
Farbe bekennen
Mit dem flachen, robusten Gehäuse aus eloxiertem Aluminium ist der iPod shuffle immer das passende Accessoire. In leuchtendem Pink, Blau, Grün, Schwarz oder Silber ist er ein echtes Fashion Statement. Ganz neu dabei: der iPod shuffle Special Edition in poliertem Edelstahl (So werden Rockstars nun mal behandelt). Sogar der iPod shuffle Clip sieht stylish aus. Er klemmt sicher an Hemd, Jacke, Sportzeug oder am Rucksack. So wird der iPod shuffle zum perfekten Fashtech-Accessoire. Und klar, natürlich ist noch Platz für eine persönliche Gravur.

Mehrsprachig
Ein französisches Chanson. Ein spanischer Bolero. Eine italienische Arie. Dein Musikarchiv enthält Musik aus allen Ländern der Welt. Deshalb spricht VoiceOver 20 Sprachen und kann die Namen von Songs und Interpreten mit der richtigen Aussprache sprechen.
 
Zufall oder kein Zufall?
Der Schalter am iPod shuffle hat drei Einstellungen. Links wird deine Musik zufällig durcheinander gewürfelt. In der Mitte werden deine Songs in der normalen Reihenfolge gespielt. Rechts wird der iPod shuffle ausgeschaltet.
";2;False;0;;;Apple iPod shuffle Tragbarer MP3-Player 4 GB 3. Generation;apple-ipod-shuffle-4-gb-blau;True;True;P-1220;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;77.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40186,8199537037;40;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000578-apple-ipod-shuffle-4-gb-blau.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000579-apple-ipod-shuffle-4-gb-blau.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000580-apple-ipod-shuffle-4-gb-blau.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Canon EOS 1000D SLR-Digitalkamera Kit;"Canon EOS 1000D SLR-Digitalkamera Kit inkl. EF-S 18-55 Objektiv ";"
Canon EOS 1000D:Anpfiff für den Aufstieg
 
Wer bislang mit der digitalen Spiegelreflexfotografie nur geliebäugelt hat, wird dieser Canon-Neuheit nur schwerlich widerstehen können: EOS 1000D heißt die neue Kamera. Die Neue punktet mit einem Preis-Leistungsverhältnis, das eine neue Canon- Liga kennzeichnet: 10,1 Megapixel CMOS-Sensor, Sieben-Punkt-Weitbereich- Autofokus und Reihenaufnahmen mit bis zu drei JPEG-komprimierten Bildern pro Sekunde. Die Marke, der die Profis vertrauen, ist also jetzt auch für den Einsteiger in die digitale Spiegelreflexfotografie erschwinglich… und dank benutzerfreundlicher Menüführung auch leicht bedienbar.
 
Die EOS 1000D ist die bislang leichteste aller digitalen EOS-Kameras und basiert auf intuitiver Bedienung und einer Reihe von innovativen Spitzentechnologien, die auch in der professionellen Serie der Canon EOS-1 Kameras zum Einsatz kommen. Dies sind beispielsweise der DIGIC-III-Bildprozessor, Livebild-Funktion und EOSIntegrated- Cleaning-System, das integrierte Sensor-Reinigungsprogramm von Canon. Die EOS 1000D gibt es auch im kostengünstigen Paket mit dem Objektiv EF-S 18- 55mm IS: Dieses Canon-Objektiv hat einen optischen Bildstabilisator, der eine längere Belichtungszeit erlaubt, weil diese Technologie Verwacklungen entgegenwirkt. Das zahlt sich besonders bei schlechten Lichtverhältnissen aus.
Intelligenter Fokus und Blitz

Bei dynamischen Aufnahmesituationen ist eine schnelle Fokussierung sehr wichtig – hier macht sich der Sieben-Punkt-Weitbereich-Autofokus der EOS 1000D durch die Scharfstellung in Sekundenbruchteilen bezahlt. Das zentrale AF-Messfeld ist ein Kreuzsensor, der sich vor allem in Aufnahmesituationen mit wenig Licht beziehungsweise schwach ausgeprägtem Kontrast bewährt. Hinzu kommt ein weiteres von den professionellen EOS-Modellen bekanntes Leistungsmerkmal: das entfernungsgekoppelte Blitzsteuerungssystem E-TTL II.
 
Konzipiert für mehr Leistung
Wie bei allen EOS-Modellen werden auch die Kernelemente der EOS 1000D von Canon selbst konzipiert und gefertigt, eine Kombination für bestmögliche Bildqualität. Der 10,1 Megapixel CMOS-Sensor sorgt für präzise, rauscharme Bilder und bietet mehr als genug Auflösung für den Fotodruck bis DIN A4. Zum Schutz vor störenden Staubpartikeln ist der Sensor der Neuen mit dem bekannten EOS Integrated Cleaning System ausgestattet, das den Staub in drei separaten Schritten bekämpft: reduzieren, abweisen und entfernen.
Die EOS 1000D verfügt mit dem DIGIC III über einen Bildprozessor, der auch bei den professionellen digitalen Canon-Spiegelreflexkameras zum Einsatz kommt. Dies ermöglicht kontinuierliche Reihenaufnahmen bis zur Kapazitätsgrenze der jeweilig eingesetzten SD- oder SDHC-Speicherkarte bei Geschwindigkeiten von bis zu drei Bildern pro Sekunde. Darüber hinaus ist der DIGIC-III-Prozessor für hochwertige Bildwiedergabe, schnelle Signalverarbeitung und nahezu umgehende Startzeiten verantwortlich.
 
 
Hoher Anwenderkomfort
Mit gerade einmal 450 Gramm (nur Gehäuse) ist die EOS 1000D die bislang leichteste digitale Canon Spiegelreflexkamera von Canon. Das kompakte, ergonomisch gestaltete Gehäuse ist konsequent auf effiziente Handhabung ausgelegt.^ Auf dem hellen 2,5 Zoll großen LC-Monitor lassen sich die Bilder umgehend überprüfen oder auch – dank des weiten Betrachtungswinkels – von mehreren Personen gleichzeitig einsehen. Ferner bietet das LC-Display Zugriff auf eine intuitive, leicht verständliche Menüstruktur mit praktischen Reitern – das ist übersichtlich und erleichtert das Auffinden von Menüpunkten.
 
Live View
Bei Aufnahmen vom Stativ oder wenn sich der Sucher als unpraktisch erweist, ermöglicht die Livebild-Funktion die Kontrolle des Motivs über das Display. Dabei wird das Livebild als Videosequenz mit 30 Bildern pro Sekunde dargestellt. Zur Beurteilung von Bildkomposition oder Belichtungseinstellung lassen sich Gitternetzlinien oder ein Histogramm einblenden. Für die Livebild-Funktion stehen zwei AF-Modi zur Verfügung: Quick AF, der zur Aktivierung des AF-Sensors umgehend den Kameraspiegel hochklappt und Live AF, der Kontrastinformationen für die Scharfstellung wie bei einer Kompaktkamera einsetzt.
 
Software
Zum Lieferumfang der EOS 1000D gehört ein umfassendes Softwarepaket mit den notwendigen Tools zur Bearbeitung und Verwaltung der Bilder. Zum Beispiel Digital Photo Professional (DPP), ein leistungsstarkes Programm zur Bearbeitung von RAWBildern. DPP bewährt sich auch im Zusammenspiel mit Kamerafunktionen wie Dust Delete Data und Picture Styles. Die im Lieferumfang enthaltene Software Picture Style Editor kann eingesetzt werden, um individuelle Picture Styles für die Feinabstimmung von Farben zu erstellen. Weitere mitgelieferte Softwareanwendungen sind EOS Utility, Image/Zoom Browser und Photostitch. 
 
EF-S 18-55 Objektiv
Speziell für digitale EOS Kameras mit EF-S-Bjonett entwickeltes Standard-Zoom
Kompakt und leicht
Hohe Bildqualität bei allen Brennweiten
Optimierte Vergütungsschichten minimieren Streulicht und Reflexe
Hohe AF-Geschwindigkeit
Sehr kurze Naheinstellgrenze
Bleifreie Optik
";2;False;0;;;"Canon EOS 1000D SLR-Digitalkamera Kit inkl. EF-S 18-55 Objektiv ";canon-eos-1000d-slr-digitalkamera-kit;True;True;P-1740;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;429.0000;0.0000;409.9000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40166,6718402778;"56;2095";25;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000481-canon-eos-1000d-slr-digitalkamera-kit.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000482-canon-eos-1000d-slr-digitalkamera-kit.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000483-canon-eos-1000d-slr-digitalkamera-kit.jpg;1;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Sandisk Sansa Fuze 8 GB schwarz;"Sandisk Sansa Fuze MP3-/Video-Player 8 GB mit Radio schwarz ";"

Sandisk Sansa Fuze MP3-/Video-Player 8 GB mit Radio schwarz

 
Mit der verfügbaren Akkuleistung können Sie 24 Stunden lang Musik hören, Bilder anschauen oder spielen.
Der neue Sansa Fuze von SanDisk ist der ideale tragbare Musikplayer für Sie.
Er steht mit einer Speicherkapazität 4 GB in schwarz,rot,pink zur Verfügung.
Sehen Sie sich Ihre Lieblingsvideoclips auf dem 1,9""-Farbdisplay des Sansa Fuze an.
Lauschen Sie dem FM-Radio mit 40 voreingestellten Sendern oder probieren Sie den integrierten Sprachrekorder aus. Mit einer unglaublich starken Akkuleistung in einem 0,3"" schmalen Gerät setzt der Sansa Fuze Zeichen.
";2;False;0;;;Sandisk Sansa Fuze MP3-/Video-Player 4 GB mit Radio;sandisk-sansa-fuze-8-gb-schwarz;True;True;P-1600;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;89.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40166,6556365741;52;8;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000480-sandisk-sansa-fuze-8-gb-schwarz.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Apple iPod shuffle 1 GB blau;Apple iPod shuffle 1 GB blau;"

Apple iPod shuffle 1GB blue 

 
Wie seine größeren Geschwister besitzt auch der iPod shuffle kreisförmig
angeordnete, ergonomische Bedienelemente.
Der Kopfhöreranschluss am iPod shuffle dient gleichzeitig als Dock-Anschluss.
Drehen Sie den iPod shuffle auf die Seite und setzen Sie ihn in das mitgelieferte Dock ein.
Dank eines stabilen, integrierten Clips lässt sich der iPod shuffle fast überall befestigen.
Klemmen Sie ihn am T-Shirt, am Hemdkragen oder am Trageriemen von Rucksack oder Handtasche fest.
Lassen Sie sich aufs Ungewisse ein: Verwenden Sie den Schalter für die Zufallswiedergabe,
um den Inhalt Ihres iPod shuffle neu zu mischen.
verbesserte Kopfhörer und das neue iTunes 8.0
 
Größe ist relativ
Natürlich kennen Sie das Sprichwort ""Weniger ist mehr"". Wie wahr dieses Sprichwort ist, beweist der neue iPod shuffle, der gerade einmal 4,1 cm lang ist, nur etwa 15 Gramm wiegt und Platz für bis zu 240 Songs bietet. Hinzu kommt, dass Sie Ihre Musik damit bis zu 12 Stunden lang ohne Unterbrechung hören können.(2) Man kann also mit Fug und Recht behaupten, dass der winzige iPod shuffle bei halber Größe viel mehr zu bieten hat, als man ihm auf den ersten Blick zutraut.
Immer im Trend
Klemmen Sie ihn an die Jeans. Oder an Ihre Handtasche. Egal, wo Sie ihn anklippen, mit Ihrem iPod shuffle haben Sie Ihre Musik jederzeit griffbereit. Das Gehäuse aus eloxiertem Aluminium passt übrigens zu jedem Outfit. Einfach festklemmen und einschalten - Sie werden ohne Zweifel viele begehrliche Blicke auf sich ziehen.
 
 
Perfekt synchronisiert
Damit Sie Ihren iPod shuffle mit bis zu 240 Songs füllen können, müssen Sie zuerst iTunes gratis laden. Danach können Sie für je 99 Cent Musiktitel aus dem iTunes Store laden oder von Ihren CDs importieren. Zum Synchronisieren schließen Sie das mitgelieferte Dock an den USB-Anschluss Ihres Mac oder PC an und übertragen die Musik aus iTunes, indem Sie den iPod shuffle in das Dock einsetzen.
 
 
Neu abgemischt
In Ihrer iTunes Bibliothek befinden sich mehr als 240 Titel? Kein Problem. Überlassen Sie es iTunes, Ihren iPod shuffle automatisch zu füllen und genießen Sie Ihre Musik jedes Mal neu. Pop folgt auf Jazz, Rock auf Ra!

 
";2;False;0;;;Apple iPod shuffle 1 GB blau;apple-ipod-shuffle-1-gb-blau;True;True;P-1110;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;49.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40160,8793055556;36;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000398-apple-ipod-shuffle-2-gb-blau.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000399-apple-ipod-shuffle-2-gb-blau.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000400-apple-ipod-shuffle-2-gb-blau.jpg;3;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Apple iPod shuffle 1 GB pink;Apple iPod shuffle 1 GB pink;"

Apple iPod shuffle 1GB pink 

 
Wie seine größeren Geschwister besitzt auch der iPod shuffle
kreisförmig angeordnete, ergonomische Bedienelemente.
Der Kopfhöreranschluss am iPod shuffle dient gleichzeitig als Dock-Anschluss.
Drehen Sie den iPod shuffle auf die Seite und setzen Sie ihn in das mitgelieferte Dock ein.
Dank eines stabilen, integrierten Clips lässt sich der iPod shuffle fast überall befestigen.
Klemmen Sie ihn am T-Shirt, am Hemdkragen oder am Trageriemen von Rucksack oder Handtasche fest.
Lassen Sie sich aufs Ungewisse ein: Verwenden Sie den Schalter für die Zufallswiedergabe,
um den Inhalt Ihres iPod shuffle neu zu mischen.
verbesserte Kopfhörer und das neue iTunes 8.0
 
Größe ist relativ
Natürlich kennen Sie das Sprichwort ""Weniger ist mehr"". Wie wahr dieses Sprichwort ist, beweist der neue iPod shuffle, der gerade einmal 4,1 cm lang ist, nur etwa 15 Gramm wiegt und Platz für bis zu 240 Songs bietet. Hinzu kommt, dass Sie Ihre Musik damit bis zu 12 Stunden lang ohne Unterbrechung hören können.(2) Man kann also mit Fug und Recht behaupten, dass der winzige iPod shuffle bei halber Größe viel mehr zu bieten hat, als man ihm auf den ersten Blick zutraut.
Immer im Trend
Klemmen Sie ihn an die Jeans. Oder an Ihre Handtasche. Egal, wo Sie ihn anklippen, mit Ihrem iPod shuffle haben Sie Ihre Musik jederzeit griffbereit. Das Gehäuse aus eloxiertem Aluminium passt übrigens zu jedem Outfit. Einfach festklemmen und einschalten - Sie werden ohne Zweifel viele begehrliche Blicke auf sich ziehen.
 
 
Perfekt synchronisiert
Damit Sie Ihren iPod shuffle mit bis zu 240 Songs füllen können, müssen Sie zuerst iTunes gratis laden. Danach können Sie für je 99 Cent Musiktitel aus dem iTunes Store laden oder von Ihren CDs importieren. Zum Synchronisieren schließen Sie das mitgelieferte Dock an den USB-Anschluss Ihres Mac oder PC an und übertragen die Musik aus iTunes, indem Sie den iPod shuffle in das Dock einsetzen.
 
 
Neu abgemischt
In Ihrer iTunes Bibliothek befinden sich mehr als 240 Titel? Kein Problem. Überlassen Sie es iTunes, Ihren iPod shuffle automatisch zu füllen und genießen Sie Ihre Musik jedes Mal neu. Pop folgt auf Jazz, Rock auf Ra!
";2;False;0;;;Apple iPod shuffle 1GB pink;apple-ipod-shuffle-1-gb-pink;True;True;P-1120;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;49.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40158,9546990741;36;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000118-apple-ipod-shuffle-2-gb-pink.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000119-apple-ipod-shuffle-2-gb-pink.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000120-apple-ipod-shuffle-2-gb-pink.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Apple iPod shuffle 1 GB grün;Apple iPod shuffle 1 GB grün;"
Apple iPod shuffle 1GB grün

 
Wie seine größeren Geschwister besitzt auch der iPod shuffle kreisförmig angeordnete, ergonomische Bedienelemente.
Der Kopfhöreranschluss am iPod shuffle dient gleichzeitig als Dock-Anschluss.
Drehen Sie den iPod shuffle auf die Seite und setzen Sie ihn in das mitgelieferte Dock ein.
Dank eines stabilen, integrierten Clips lässt sich der iPod shuffle fast überall befestigen.
Klemmen Sie ihn am T-Shirt, am Hemdkragen oder am Trageriemen von Rucksack oder Handtasche fest.
Lassen Sie sich aufs Ungewisse ein: Verwenden Sie den Schalter für die Zufallswiedergabe, um den Inhalt Ihres iPod shuffle neu zu mischen.
verbesserte Kopfhörer und das neue iTunes 8.0
 
Größe ist relativ
Natürlich kennen Sie das Sprichwort ""Weniger ist mehr"". Wie wahr dieses Sprichwort ist, beweist der neue iPod shuffle, der gerade einmal 4,1 cm lang ist, nur etwa 15 Gramm wiegt und Platz für bis zu 240 Songs bietet. Hinzu kommt, dass Sie Ihre Musik damit bis zu 12 Stunden lang ohne Unterbrechung hören können.(2) Man kann also mit Fug und Recht behaupten, dass der winzige iPod shuffle bei halber Größe viel mehr zu bieten hat, als man ihm auf den ersten Blick zutraut.
Immer im Trend
Klemmen Sie ihn an die Jeans. Oder an Ihre Handtasche. Egal, wo Sie ihn anklippen, mit Ihrem iPod shuffle haben Sie Ihre Musik jederzeit griffbereit. Das Gehäuse aus eloxiertem Aluminium passt übrigens zu jedem Outfit. Einfach festklemmen und einschalten - Sie werden ohne Zweifel viele begehrliche Blicke auf sich ziehen.
 
 
Perfekt synchronisiert
Damit Sie Ihren iPod shuffle mit bis zu 240 Songs füllen können, müssen Sie zuerst iTunes gratis laden. Danach können Sie für je 99 Cent Musiktitel aus dem iTunes Store laden oder von Ihren CDs importieren. Zum Synchronisieren schließen Sie das mitgelieferte Dock an den USB-Anschluss Ihres Mac oder PC an und übertragen die Musik aus iTunes, indem Sie den iPod shuffle in das Dock einsetzen.
 
 
Neu abgemischt
In Ihrer iTunes Bibliothek befinden sich mehr als 240 Titel? Kein Problem. Überlassen Sie es iTunes, Ihren iPod shuffle automatisch zu füllen und genießen Sie Ihre Musik jedes Mal neu. Pop folgt auf Jazz, Rock auf Ra!
";2;False;0;;;Apple iPod shuffle 1 GB grün;apple-ipod-shuffle-1-gb-gruen;True;True;P-1100;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;49.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40158,9517476852;36;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000429-apple-ipod-shuffle-2-gb-grun.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000430-apple-ipod-shuffle-2-gb-grun.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000431-apple-ipod-shuffle-2-gb-grun.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Panasonic DMR EX 72 SEG DVD HDD RECORDER;Panasonic DMR EX 72 SEG DVD- und HDD-Rekorder 160 GB;"

Panasonic DMR EX 72 SEG DVD- und HDD-Rekorder 160 GB

mit integriertem DVB-S Tuner
 
HDD/DVD Recorder/Farbe: schwarz/ Festplattenspeicher: 160 GB/ Tuner: DVB-S/ Sonderfunktionen: EPG/ Anschlüsse: 2x Scart, 3x Cinch (Komponenten/YUV),
Cinch (Composite / Video / FBas), HDMI (mit HDCP), S-Video (Hosiden), USB/ B: 430 mm/ H: 59 mm
Art HDD/DVD Recorder
Farbe schwarz
Festplattenspeicher 160 GB
Tuner DVB-S
Sonderfunktionen EPG
Anschlüsse 2x Scart / 3x Cinch (Komponenten/YUV) / Cinch (Composite / Video / FBas) / HDMI (mit HDCP) / S-Video (Hosiden) / USB
Breite 430 mm
Höhe   59 mm
Tiefe  286 mm
Gewicht netto 3,7 kg
Aufnahme DVD+R / DVD+RW / DVD-R / DVD-RAM / DVD-RW
Wiedergabe Audio-CD / CD-R / CD-RW / DVD / DVD+R / DVD+RW / DVD-R / DVD-RAM / DVD-RW / JPEG / MP3 / S-Video CD / WMA
";2;False;0;;;Panasonic DMR EX 72 SEG DVD HDD RECORDER;panasonic-dmr-ex-72-seg-dvd-hdd-recorder;True;True;P-1850;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;399.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40155,86625;62;12;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000471-panasonic-dmr-ex-72-seg-dvd-hdd-recorder.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000472-panasonic-dmr-ex-72-seg-dvd-hdd-recorder.jpg;;1;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Panasonic DMR EH 495 EG K 160 GB DVD/ HDD Rekorder;Panasonic DMR EH 495 EG K 160 GB DVD/ HDD Rekorder;"
Panasonic DMR EH 495 EG K 160 GB DVD/ HDD Rekorder

HDMI, DivX-zertifiziert, USB 2.0

Mit dem DMR-EH495 präsentiert Panasonic, Marktführer bei DVD-Rekordern, neue Multiformat-DVD-Festplatten-Kombinationen. Sie bieten alle Komfortmerkmale der testbewährten Vorjahresmodelle, begeistern mit noch mehr Details sowie einer intuitiven Benutzerführung. Die mit einem analogen Tuner ausgestatteten Geräte verfügen über eine integrierte Festplatte und zeichnen auf alle gängigen DVD-Formate auf. Neben der Aufnahme des Fernsehprogramms überzeugen die neuen Rekorder als digitales Fotoalbum sowie Musik-Jukebox und werden somit zur Unterhaltungszentrale im Wohnzimmer. Komfortfunktionen wie der elektronische Programmführer Guide Plus+ mit Suchfunktion, eine automatische Kapitelerstellung, umfangreiche Anschlussmöglichkeiten sowie ein hochwertiger Upscaler machen die Rekorder zu Multitalenten. Darüber hinaus schont der weiterentwickelte Eco-Modus Umwelt und Geldbeutel.
 
Die Rekorder DMR-EH495 zeigen sich als wahre Alleskönner und zeichnen auf Festplatte oder DVD auf.
Sie verarbeiten alle gängigen DVD-Formate wie DVD-RW, -R (DL), DVD+RW/+R (DL) sowie DVD-RAM. Außerdem können CDs, CD-R/-RWs sowie MP3- und JPEG-Daten sowohl von DVD als auch CD abgespielt werden.
Die integrierte Festplatte erlaubt die Aufzeichnung von Fernsehprogrammen. Somit ist auch bei längerer Abwesenheit genügend Platz für die Lieblingsserie vorhanden.
Dank des integrierten, elektronischen Programmführers Gemstar Guide Plus+ erfolgen die Programmauswahl und Timerprogrammierung kinderleicht und intuitiv.
Die übersichtliche Darstellung des Fernsehprogramms bietet neben einer Genre-Auswahl zusätzlich eine gezielte Suche nach Stichworten.
 
So kann beispielsweise direkt nach Schauspielern, Themen oder Sportarten gesucht werden. Neben dieser Funktion arbeiten die neuen Rekorder mit einer automatischen Kapitelerstellung bei der Aufzeichnung.
Dadurch können während der anschließenden Wiedergabe unerwünschte Programmsequenzen auf Knopfdruck übersprungen oder eine Szene blitzschnell gefunden werden.
Mit Pause Live TV kann zudem das laufende Fernsehprogramm jederzeit mit einem Druck auf die Pause-Taste angehalten und zu einem späteren Zeitpunkt weitergeschaut werden.
Dank Quick Start-Funktion sind die Rekorder innerhalb einer Sekunde einsatzbereit, so dass kein Film und keine Aufzeichnung verpasst werden.
 
  • Multiformat-DVD-Festplatten-Kombination
  • Intuitive Benutzerführung
  • Neben der Aufnahme des Fernsehprogramms überzeugen die neuen Rekorder als digitales Fotoalbum sowie
  • Musik-Jukebox
  • Elektronische Programmführer Guide Plus+ mit Suchfunktion
  • Umfangreiche Anschlussmöglichkeiten
";2;False;0;;;Panasonic DMR EH 495 EG K;panasonic-dmr-eh-495-eg-k-160-gb-dvd-hdd-rekorder;True;True;P-1840;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;319.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40155,8616898148;62;12;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000428-panasonic-dmr-eh-495-eg-k-160-gb-dvd-hdd-rekorder.jpg;;;3;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"HP Compaq Mini 110c-1110sg 10.1 Zoll Netbook ";"HP Compaq Mini 110c-1110sg 10.1 Zoll Netbook ";"
HP Compaq Mini 110c-1110sg 10.1 Zoll Netbook
 
Intel Atom N270 1.6GHz, 1GB RAM, 160GB HDD, Intel GMA 950, Win XP Home
 
Leicht und kompakt
Der Compaq Mini 110c wiegt 1,3 kg (mit 6-Zellen-Akku) und ist ca. 5,5 cm hoch – er ist damit sehr kompakt und fällt ins Auge
 
Elegantes Design
Der Compaq Mini 110c glänzt mit einem eleganten Gehäuse im neuem Imprint-Finish ""Unity"", einem Karomuster, das ins Auge fällt.
 
Ständig in Verbindung
Webcam und Mikrofon sind im Compaq Mini integriert und bieten per WLAN und optionalem WWAN zahlreiche Möglichkeiten zur Pflege sozialer Kontakte; Video-Chats und Video-Konferenzen, die bislang nur zuhause möglich waren, können jetzt im Park, im Cafe oder am Flughafen geführt werden
 
Information und Kommunikation auch unterwegs
Mit dem 10,1-Zoll-BrightView-Display, Original Windows® XP Home, der großen Tastatur (92 % der vollen Größe), drei USB-Anschlüssen und einem 5-in-1 Kartenleser sind Informationen, Kommunikation und Unterhaltung im Internet überall bequem zugänglich.
";2;False;0;;;"HP Compaq Mini 110c-1110sg 10.1 Zoll Netbook ";hp-compaq-mini-110c-1110sg-101-zoll-netbook;True;True;P-0870;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;259.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40151,9990046296;6;39;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000598-hp-compaq-mini-110c-1110sg-101-zoll-netbook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000599-hp-compaq-mini-110c-1110sg-101-zoll-netbook.jpg;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Apple iPod Classic 120 GB schwarz;"Apple iPod Classic 120 GB schwarz ";"

Apple iPod Classic 120 GB schwarz

 
iPod classic: Freiraum -Und zwar jede Menge.
120 GB sind wirklich eine ganze Menge Platz. Da lässt sich eine komplette Mediathek locker unterbringen und überallhin mitnehmen.
 
Ein musikalisches Genie
Stellen Sie vor, Sie hören einen Song. Toll wären jetzt andere Titel, die gut dazu passen. Was machen Sie? Ganz einfach: Sie verwenden die neue Funktion ""Genius"". Diese findet die Songs in Ihrer Mediathek, die gut zusammenpassen. Sie erhalten eine Genius Wiedergabeliste, die Sie sofort anhören, sichern oder sogar aktualisieren können. Verlassen Sie sich also auf den Genius von iTunes, wenn Sie einen Mix wollen, auf den Sie selbst nicht gekommen wären.
 
Platz satt
Der iPod classic bietet mit seinen 120 GB Speicherkapazität Platz für bis zu 30.000 Songs, 180 Stunden Videos, 20.000 Fotos oder eine beliebige Kombination dieser Inhalte. Und mit bis zu 36 Stunden Batterielaufzeit beweist der iPod classic auch ganz schön viel Kondition.
 
Spaß auf Knopfdruck
Sie findeen immer ganz leicht genau das, was Sie sehen oder hören wollen. Mit dem Click Wheel können Sie mit ""Cover Flow"" Ihre Alben durchblättern, oder Sie stöbern über verschiedene Kategorien wie Wiedergabeliste, Künstler, Album oder Musikrichtung in Ihren Songs und Videos. Sie können natürlich auch nach einem bestimmten Titel oder Interpreten suchen. Lust auf einen neuen Mix? Klicken Sie einfach auf ""Zufällige Titel"".
 
Filme und Fernsehsendungen ansehen
Auf dem fantastischen 2,5"" Display kommen Videos richtig zur Geltung. Sie können im iTunes Store Filme kaufen oder ausleihen, Fernsehsendungen kaufen und Video-Podcasts laden. Dann können Sie alles mit Ihrem iPod classic synchronisieren und immer und überall ansehen.
 
 
Spiele auf dem iPod
Wenige Fingertipps, viele Stunden Spielspaß. Vortex, iQuiz und Klondike sind schon auf dem iPod classic vorinstalliert, im iTunes Store können Sie weitere dazukaufen, z. B. Cake Mania. Alle iPod Spiele sind speziell für die iPod Oberfläche optimiert.
 
Fotos zeigen
Ihre Fotos aus iPhoto auf einem Mac oder aus Adobe Photoshop Elements und Adobe Photoshop Album auf einem PC bekommen Sie mit iTunes auf den iPod classic. Sie können Diashows mit Musik und Übergängen auf dem iPod classic oder mit optional erhältlichen Apple Komponenten oder mit einem Composite-AV-Kabel sogar auf dem Fernseher zeigen.
 
Umweltverträglichkeit
Der iPod classic steht für das kontinuierliche Engagement von Apple in puncto Umweltschutz. Die folgenden Merkmale tragen zu einer geringen Umweltbelastung bei:
 
    Arsenfreies Displayglas
    Ohne bromhaltige Flammschutzmittel
    Display mit LED-Hintergrundbeleuchtung ohne Quecksilber
    Frei von PVC
    Recyclingfähiges Gehäuse aus Aluminium und Edelstahl
 
Produktbeschreibungen
Freiraum. Und zwar jede Menge. 160 GB sind wirklich eine ganze Menge Platz. Da lässt sich eine komplette Mediathek locker unterbringen und überallhin mitnehmen.
 
> Highlights
- Click Wheel
- Frequenzbereich: 20 Hz bis 20.000 Hz
- Weitere unterstützte Audioformate: Protected AAC (aus dem iTunes Store), MP3 VBR, Audible (Formate 2, 3, 4, Audible Enhanced Audio, AAX und AAX+), Apple Lossless und WAV
- Platz für bis zu 35.000 Songs im 128 KBit/Sek. AAC-Format
- Platz für bis zu 20.000 vom iPod anzeigbare Fotos
- Platz für bis zu 180 Stunden Videomaterial
- Speichert Daten auf einer USB-Festplatte
- Akkuladezeit: ca. 4 Std. (schnelles Laden auf 80%ige Kapazität in 2 Std.)
 
> Grundeigenschaften
- Breite: 103.5 mm
- Höhe: 61.8 mm
- Tiefe: 10.5 mm
- Gewicht: 140.0 g
- Farbe: Schwarz
 
> Wiedergabeformate Audio
- AAC
- MP3
- WAV
 
> Akku
- Akkutyp: Li-Ion
 
> Display
- Displaytechnologie: LCD
- 2.5- Display
- Bilddiagonale: 6.35 cm
- Auflösung Breite: 320 Pixel
- Auflösung Höhe: 240 Pixel
- Hintergrundbeleuchtung: ja
 
> Speicher
- Speicherkapazität 120 GB
 
> Anschlüsse
- USB
- USB-Standard 2.0
 
> Audio-Anschlüsse
- Headsetanschluss: 3,5 mm Klinke
- ipod-Anschluss via IPOD Connector
 
> Lieferumfang
- iPod classic
- Apple Earphones
- USB 2.0 Kabel
- Dock-Adapter
- Dokumentation
 
> Umweltverträglichkeit
Der iPod nano steht exemplarisch für das Engagement von Apple in puncto Umweltschutz. Die folgenden Merkmale des iPod nano tragen zu seiner geringeren Umweltbelastung bei:
- Arsenfreies Glas
- Frei von bromhaltigen Flammschutzmitteln
- Frei von Quecksilber
- Frei von PVC
- Besonders recyclingfähig
";2;False;0;;;Apple iPod Classic 120 GB schwarz;apple-ipod-classic-120-gb-schwarz;True;True;P-1420;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;209.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40151,9525462963;50;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000284-apple-ipod-classic-160-gb-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000285-apple-ipod-classic-160-gb-schwarz.jpg;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Garmin nüvi 1370T Navigationssystem ";"Garmin nüvi 1370T Navigationssystem Europa USA ";"
Garmin nüvi 1370T Navigationssystem
 
 

TMC, 4,3"" Display, Europa / USA / Kanada, ecoRoute, Fußgängernavigation, Bluetooth

 
 
 
Mobile Navigation für die ganze Familie, dank Fahrspurassistent, intelligentem TMC, und Text-to-Speech eine rund-um-sorglos Navigation
Übersichtliche und einfache Navigation mit 4,3 Zoll Display mit Fahrspurassistent + TMC Verkehrsfunkempfänger zur Stauumfahrung
Kartenmaterial für Europa, USA und Canada intern vorinstalliert
Inklusive ecoRoute die Garmin Spritspar-Funktion und echter Fußgängernavigation mit optionalen CityXplorer Stadtplänen für Bus und Bahn
Lieferumfang: Garmin nüvi 1370T mit Kartenmaterial Europa/ USA/ Canada, KFZ-Anschlusskabel mit TMC Verkehrsfunkempfänger,
Saugnapfhalterung für die Windschutzscheibe, Armaturenhalterung, Kurzanleitung
";2;False;0;;;"Garmin nüvi 1370T Navigationssystem ";garmin-nuevi-1370t-navigationssystem;True;True;P-2100;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;359.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40148,9306828704;67;44;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000589-garmin-nuvi-1370t-navigationssystem.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;NAVIGON 8410 Navigationssystem Europa;" NAVIGON 8410 Navigationssystem Europa 5"" Echtglas-Display";"
NAVIGON 8410 Navigationssystem Europa
 
 
5"" Echtglas-Display, West & Osteuropa 40 Länder, Bluetooth, TMC Pro, Real City 3D, Voice Interaction Pro
 
 
5-Zoll-Touchdisplay 16:9
Fußgängernavigation
Reality View Pro
Fahrspurassistent Pro
Radar-Info
Geschwindigkeitsassistent
Reale Beschilderung Pro
Clever Parking
Text-to-Speech für Straßennamen
Bluetooth Freisprecheinrichtung
Professionelle Sprachsteuerung 2.0
Landmark View 3D/City View 3D
Panorama View 3D
Latest Map Guarantee
Europakarte (40 Länder)
Abmessungen: 138 mm x 83,5 mm x 18,7mm (B/H/T)
Lieferumfang: NAVIGON 8410, Kurzanleitung, KfZ-Ladekabel mit integrierter TMC Antenne,
Design-Aktivhalterung, USB-Kabel, vorinstalliertes Europa-Kartenmaterial
";2;False;0;;;"NAVIGON 8410 Navigationssystem ";navigon-8410-navigationssystem-europa;True;True;P-2170;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;449.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40148,9205902778;"68;2095";14;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000470-navigon-8410-navigationssystem-europa.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Apple iPod shuffle 2 GB blau;Apple iPod shuffle 2 GB blue;"

Apple iPod shuffle 2GB blau 

 
 
Wie seine größeren Geschwister besitzt auch der iPod shuffle kreisförmig
angeordnete, ergonomische Bedienelemente.
Der Kopfhöreranschluss am iPod shuffle dient gleichzeitig als Dock-Anschluss.
Drehen Sie den iPod shuffle auf die Seite und setzen Sie ihn in das mitgelieferte Dock ein.
Dank eines stabilen, integrierten Clips lässt sich der iPod shuffle fast überall befestigen.
Klemmen Sie ihn am T-Shirt, am Hemdkragen oder am Trageriemen von Rucksack oder Handtasche fest.
Lassen Sie sich aufs Ungewisse ein: Verwenden Sie den Schalter für die Zufallswiedergabe,
um den Inhalt Ihres iPod shuffle neu zu mischen.
verbesserte Kopfhörer und das neue iTunes 8.0
 
Einfach Musik anhaben mit dem Apple iPOD SHUFFLE 2GB.Tragen Sie bis zu 500 Songs am Ärmel. Oder am Gürtel. Oder am Sportoutfit. Das Erkennungszeichen für Musikfans - den Apple iPOD SHUFFLE. Füllen Sie Ihren Apple iPOD SHUFFLE silber 1GB spielend einfach. iTunes ist der Store für Unterhaltungsinhalte. Ihre super organisierte Musiksammlung und Jukebox. Und die Software, mit der Sie Ihren Apple iPOD SHUFFLE mit einem Mausklick füllen. Das farbige Gehäuse aus eloxiertem Aluminium in silber passt zum genial einfachen Design des Apple iPOD SHUFFLE.
 
Leistungseigenschaften
 
2 GB Flash-Memory Speicher
min. Audio-Datenrate: 8 KBit/s
max. Audio-Datenrate: 320 KBit/s
Frequenzgang-Untergrenze: 20 Hz
Frequenzgang-Obergrenze: 20000 Hz
 
Formate/Standards
 
MP3-Standard
AAC + MP3 Standard
WAV-Dateiformat kompatibel
Audible-Format kompatibel
AIFF-Format kompatibel
 
Bedienung
 
Musiktitel-Verwaltung
 
Leistungsaufnahme/Spannungsversorgung

Li-Polymer Akku
12 Std. Spieldauer mit Akku
Ladezeit für Akku: 4 Std.
 
Anschlüsse
 
Kopfhörer-Anschluß
USB-Schnittstelle
Anschluß für Docking-Station
 
Gehäuse-Eigenschaften
 
Breite: 4.12 cm
Höhe: 2.73 cm
Tiefe: 1.05 cm
Gewicht: 15.5 g
";2;False;0;Apple iPod shuffle 2 GB blau;Apple iPod shuffle 2 GB blau;Apple iPod shuffle 2 GB blau;apple-ipod-shuffle-2-gb-blau;True;True;P-1150;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;64.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40148,0555902778;37;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000398-apple-ipod-shuffle-2-gb-blau.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000399-apple-ipod-shuffle-2-gb-blau.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000400-apple-ipod-shuffle-2-gb-blau.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Logitech EX 110 Desktop Tastatur/Maus ";Logitech EX 110 Desktop Tastatu / Maus;"
Logitech EX 110 Desktop Tastatur/Maus
 
 
Zuverlässig und kabellos:
Schnelle, kabellose 27-MHz-Leistung
Sondertasten: Zugriff auf Musik, Video, Lautstärke, E-Mail, Internet und mehr.
Programmierbare F-Tasten: öffnen häufig genutzter Anwendungen, Websites oder Dateien.
Spritzwassergeschütztes Design
Maus: Schnell ansprechende Optik: Erleben Sie eine Auflösung von 800 dpi.
 
Lieferumfang:
Logitech Cordless Keyboard und Cordless Optical Mouse,
kompakter USB-/PS/2-Funkempfänge, USB-PS/2-Adapter
 
";2;False;0;;;"Logitech EX 110 Desktop Tastatur/Maus ";logitech-ex-110-desktop-tastaturmaus;True;True;P-2810;;;False;0;False;;False;False;0;False;0;1;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;24.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40143,0133101852;"21;2095";11;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000392-logitech-ex-110-desktop-tastaturmaus.jpg;;;1;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"TomTom GO 940 Live Navigationssystem ";"TomTom Go 940 Live Navigationssystem Europa Nordamerika ";"
TomTom GO 940 Live Navigationsgerät mit Sprachsteuerung

 
inkl. Europa-Karten, USA, Kanada, TMC, Live Services

 
Clevere Navigation mit Echtzeitinfos für Vielfahrer und dem neuesten Kartenmaterial von West- und Osteuropa, USA und Kanada, TomTom IQ Routes -
jeden Tag zu jeder Tageszeit die optimalste Route, TomTom Map Share, vereinfachte Bedienung durch brillianten 4,3-Zoll-Touchscreen und Sprachsteuerung,
verbesserter Fahrspurassistent zur einfacheren Orientierung an unübersichtlichen Autobahnkreuzen, hochwertiger Bluetooth-Kfz-Freisprecheinrichtung sowie einem FM-Transmitter und MP3-Player.
TomTom GO 940 Live inklusive 3 Monate Probe-Abo zu Live-Dienste in allen LIVE Ländern. Echtzeit-Empfang von Premiuminformationen zu Ihrer Route: HD Traffic, Lokale Suche mit Google, Sicherheitswarnungen und mehr
 Sprachsteuerung - mehr als 100 Funktionen einfach per Sprachbefehl aktivieren
Verbesserte Positionsbestimmung - unterbrechungsfreie Navigation, sogar in Tunneln
Fahrspurassistent - zum einfachen Navigieren an unübersichtlichen Kreuzungspunkten
GO 940 LIVE: Karten von Europa (WE u. OE), den USA und Kanada vorinstalliert, LIVE-Services- fahren Sie immer aktuell und zuverlässig informiert mit Echtzeit-Informationen
sowie mit IQ Routes damit fahren Sie zu jeder Tageszeit auf der cleversten Route
Lieferumfang: TomTom GO 940 LIVE, aktive Halterung, Autoladegerät, Halterung für Zuhause, Benutzerhandbuch, CD-ROM (TomTom HOME )

 
";2;False;0;;;;tomtom-go-940-live-navigationssystem;True;True;P-2010;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;304.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40136,6372800926;66;4;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000391-tomtom-go-940-live-navigationssystem.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Apple iPod Touch 8 GB schwarz;"Apple iPod Touch 8 GB schwarz mit integrierter WiFi Funktion ";"
Apple iPod Touch 32 GB schwarz mit integrierter WiFi Funktion

Der iPod touch kann alles, was du am iPod toll findest. Und noch vielmehr. Schlankes neues Design. Mit seinem fantastisch flachen Edelstahl-Design liegt der iPod touch mit dem 3.5 Zoll Touch-Display jetzt noch besser in der Hand. Mobil im Spiel. Durch revolutionäre Technologien wie das Multi-Touch-Display, der Beschleunigungssensor und 3D-Grafiken macht das Spielen auf dem iPod touch besonders viel Spaß. Schlaue Musik Mit der neuen Funktion ""Genius"" wird der iPod touch zu Deinem superintelligenten, persönlichen DJ.
Nur ein paar Fingertipps, und Genius erzeugt eine Wiedergabeliste mit Songs Deiner Mediathek, die gut zusammenpassen. Internet überall Internetzugang überall, wo ein drahtloses Netzwerk zur Verfügung steht, damit Sie immer mit dabei sind. Multitouch-Oberfläche: Die revolutionäre Technologie des iPhone und die Software Version 3.1 stecken in diesem genialen iPod. Das brillante Breitformat-Display rückt Ihre Videos und Spiele ins beste Licht und dank OpenGL sehen die Spiele jetzt noch besser aus Surfen Sie mit Safari im Web und sehen Sie YouTube Videos auf dem iPod mit integrierter Wi-Fi Funktionalität an. Mit Ihrem iPod touch können Sie im iTunes Wi-Fi Music Store nach Songs suchen, Hörproben abspielen und Titel kaufen.
Lieferumfang: iPod touch, Ohrhörer, USB 2.0 Kabel, Kurzanleitung
 
Schlankes neues Design
Mit seinem fantastisch flachen Edelstahl-Design liegt der iPod touch so gut in der Hand wie nie zuvor. Ebenfalls Eindruck machen der neue Lautstärkeregler und der integrierte Lautsprecher.

Spiele
Speziell auf die iPod touch Technologie zugeschnittene Spiele sind nur noch einen Fingertipp entfernt. Stöbere in hunderten von Spielen im App Store direkt auf Deinem iPod touch, und wenn Du gefunden hast, was Du suchst, kannst Du es einfach laden und dann kann es losgehen.
 
Steuerung per Fingertipp
Viele Spiele auf dem iPod touch nutzen die Multi-Touch-Technologie für besonders exakte Fingertipp-Steuerung der verschiedenen Spielelemente. Beim Schach ziehst Du mit dem Finger die Figuren, bei Würfelspielen bewegst Du die Würfel. Durch Ziehen mit zwei Fingern kannst Du die Anzeige vergrößern und verkleinern, Deine Figur nach links oder rechts drehen, und durch einfaches Antippen triffst Du eine Auswahl.
 
Musik
Blättere in den Albumcovern Deiner Musiksammlung. Erstelle immer wieder neue Genius Wiedergabelisten und erweitere Deine Sammlung aus dem iTunes Wi-Fi Music Store überall, wo ein Wi-Fi-Hotspot in der Nähe ist.
Mit Cover Flow lebt das Flair einer CD- oder Plattensammlung wieder auf. Wer erinnerst sich nicht an das Gefühl beim Durchblättern der Sammlung? Das gibt es jetzt auch auf dem iPod touch: einfach iPod drehen, durch die Cover blättern, ein Album auswählen, fertig. Ein Fingertipp aufs Cover, und schon siehst Du die Titelliste, ein weiterer Tipp spielt die Musik ab, und dabei kannst Du sogar die Songtexte anzeigen.
 
Ein Musikgenie
Stell Dir vor, Du hörst einen Song. Toll wären jetzt andere Titel, die gut dazu passen. Was machst du? Ganz einfach: Du verwendest die neue Funktion ""Genius"". Diese findet die Songs in Deiner Mediathek, die gut zusammenpassen. Du erhältst eine Genius Wiedergabeliste, die Du sofort anhören, sichern oder sogar aktualisieren kannst. Verlass Dich also auf den Genius von iTunes, wenn Du einen Mix willst, auf den Du selbst nicht gekommen wärst.
 
Lautsprecher integriert
Mit dem integrierten Lautsprecher kannst Du Musik und Gespräche ohne Kopfhörer hören – perfekt für zwangloses Hörvergnügen.

Längere Batterielaufzeit
Jetzt kannst Du noch länger rocken (und ansehen und spielen). Der iPod touch hält bis zu 36 Stunden bei Musik oder bis zu 6 Stunden bei Videos durch. Das reicht für drei oder vier Filme zwischen den Ladevorgängen.
 
Internet
Surfe im Internet mit Wi-Fi. Du kannst detailgenaue HTML-E-Mails mit Anlagen empfangen und Wegbeschreibungen und aktuelle Verkehrsinformationen abrufen. Auch als YouTube-Fan entgeht Dir nichts.
 
Überall ins Internet
Der iPod touch ist der einzige iPod mit kabellosem 802.11b/g Internetzugriff. Bei bestehender Wi-Fi-Verbindung kannst Du im Internet surfen und Nachrichten lesen, Sportergebnisse sehen, Rechnungen bezahlen und online einkaufen.
 
Wer suchet, der findet
Der iPod touch synchronisiert Deine Lesezeichen vom PC oder Mac, sodass Du ruck zuck auf Deine Lieblingsseiten zugreifen kannst. Die Google- und Yahoo!-Suche ist schon integriert, sodass Du im Web schnell findest, was Du suchst.
 
Zoom mit Aussicht
Jeden beliebigen Ausschnitt einer Webseite kannst Du vergrößern, indem Du mit dem Finger darauf tippst oder mit zwei Fingern die Anzeige aufziehst. Websites lassen sich im Hoch- oder Querformat anzeigen: einfach den iPod touch um 90 Grad drehen, und schon wird auch die Darstellung der Website gedreht.
 
Eigene Weblinks
Für häufig besuchte Websites, etwa die einer Zeitung, eines Blogs oder eine Sport-Website, kannst Du einfach ein Symbol auf dem Home-Bildschirm erstellen. Deine Lieblingsseiten sind über mit Safari erstellte Weblinks nur einen Fingertipp entfernt.
 
Rock 'n' Run mit Nike+
Im iPod touch ist kabellose Unterstützung für Nike + iPod integriert. Du brauchst nur einen Nike + iPod Sensor in Deinem Schuh, und schon kann's losgehen.
 
Das optimale Lauftraining
Im iPod touch ist jetzt Unterstützung für Nike + iPod integriert. Einfach den Nike + iPod Sensor (separat erhältlich) in den Nike+ Laufschuh einsetzen, und es kann losgehen. Der Sensor überträgt die Laufdaten drahtlos an den iPod touch – er erfasst die gelaufene Zeit, die zurückgelegte Strecke und die verbrauchten Kalorien. Außerdem gibt er Dir gesprochenes Feedback zu Deinen Trainingsfortschritten.
 
Das optimale Fitnesstraining
Diese Funktion kann auch zusammen mit neuen, in vielen Fitnessstudios vorhandenen Geräten für das Ausdauertraining gekoppelt werden. Suche einfach nach mit Nike + iPod kompatiblen Laufbändern, Elliptical Trainern, Steppern und Hometrainern.
";2;False;0;;;Apple iPod Touch 8 GB schwarz mit integrierter WiFi Funktion;apple-ipod-touch-8-gb-schwarz;True;True;P-1270;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;169.9000;169.9000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40134,2799768519;43;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000141-apple-ipod-touch-16-gb-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000142-apple-ipod-touch-16-gb-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000143-apple-ipod-touch-16-gb-schwarz.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Philips DVP 5990 / 12 DVD Player ";Philips DVP 5990 / 12 DVD Player schwarz;"
Philips DVP 5990 / 12 DVD Player schwarz
 
DivX-zertifiziert, HDMI 1080p, Upscaling 1080i
 
Der ideale DVD-Player für Ihr HDTV
mit True High-Definition-HDMI 1080p
Lassen Sie sich von diesem DVD-Player von Philips mit HDMI Digital Video- und
Audioverbindung beeindrucken. Erleben Sie wahres Home Entertainment, und tauchen
Sie in High Definition Video ein (720p / 1080i / 1080p).
Digitaler HDMI-Ausgang für eine einfache Verbindung mit nur einem Kabel
DivX Ultra-zertifiziert für verbesserte Wiedergabe von DivX-Videos
192 kHz/24 Bit Audio-DAC für verbesserte analoge Klangausgabe
Hochwertige Ausgänge für Analog- und Digital-Audio
 
Lieferumfang:
DVD Player; 2 AAA-Batterien; Schnellstartanleitung; Fernbedienung; Benutzerhandbuch
";2;False;0;;;"Philips DVP 5990 / 12 DVD Player ";philips-dvp-5990-12-dvd-player;True;True;P-1930;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;89.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40132,644837963;60;6;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000383-philips-dvp-5990-12-dvd-player.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000384-philips-dvp-5990-12-dvd-player.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000385-philips-dvp-5990-12-dvd-player.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Sandisk Sansa Clip+ schwarz 8GB;Sandisk Sansa Clip+ schwarz 8 GB;"
Sandisk Sansa Clip+ schwarz 8 GB
 
 
 
Die neuen Sandisk Sansa Clip+ - Modelle unterstützen nun die Anzeige von sortierbaren Ordnerstrukturen.
digitaler SanDisk Player für MP3, WMA, Secure WMA, Ogg Vorbis, FLAC-Formate, Hörbücher und FM-Radio
kleines, kompaktes Design, kaum größer als eine Streichholzschachtel
microSD-/microSDHC-Slot zur Erweiterung der Speicherkapazität und zum Datentransfer
FM-Radio mit 40 Stationsspeicherplätzen
Diktiergerät-Funktion über integriertes Mikrofon
4-zeiliges OLED-Display
Sortierung der Titel nach verschiedenen Kriterien möglich, wie z.B. Künstler, Album, Genre, u.a.
bis zu 15-h-Wiedergabe mittels internem, wiederaufladbaren Akku
inkl. abnehmbarem Trageclip, Ohrhörer, USB 2.0 Kabel und Bedienungsanleitung
unterstützt Win 2000, Vista, XP SP2 und Mac OS X 10.3 oder höher
Speicherkapazität extern: wird über microSD-Karte definiert
Speicherkapazität intern: 8 GB
Speicher: intern + extern

Lieferumfang:
Sansa Clip+ MP3 Player, Ohrhörer, USB 2.0 Kabel, Quick Start Guide
";2;False;0;;;Sandisk Sansa Clip+;sandisk-sansa-clip-schwarz-8gb;True;True;P-1590;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;59.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40125,6367476852;52;8;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000572-sandisk-sansa-clip-schwarz-8gb.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Me2 ME600HD-1000 Multimediafestplatte ";"Me2 ME600HD-1000 Multimediafestplatte1 TB ";"

Me2 ME600HD-1000  Multimediafestplatte 1 TB

 
 
3,5 Zoll, USB 2.0,Scart,HDMI Multimedia
 
 
 
Externe USB 2.0 Multimedia Festplatte• Kapazität: 1000 GB• High-speed
USB 2.0 Schnittstelle• Aluminium Gehäuse• Stand-alone Media Player zur Wiedergabe von MPEG-1, MPEG-2,
D ivX/Xvid, JPEG, GMC, Qpel, MP3 (ID3 tag) WAV Media Daten• direkte Wiedergabe von DVD Ordnern&bu
Ordner-Navigation• Eigene Playlist benutzen und bearbeiten• einfache Dateiführung,
 intuitive Bedienung• unterstützt NTSC und PAL TV Standard• geeignet für HDTV (skaliert auf 10
";2;False;0;;;;me2-me600hd-1000-multimediafestplatte;True;True;P-2670;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;169.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40124,2896180556;16;;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000117-me2-me600hd-500-gb-multimediafestplatte.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Apple iPod Classic 160 GB silber;"Apple iPod Classic 160 GB silber ";"
Apple iPod Classic 160 GB silber


iPod classic: Freiraum -Und zwar jede Menge.
160 GB sind wirklich eine ganze Menge Platz. Da lässt sich eine komplette Mediathek locker unterbringen und überallhin mitnehmen.
 
Ein musikalisches Genie
Stellen Sie vor, Sie hören einen Song. Toll wären jetzt andere Titel, die gut dazu passen. Was machen Sie? Ganz einfach: Sie verwenden die neue Funktion ""Genius"". Diese findet die Songs in Ihrer Mediathek, die gut zusammenpassen. Sie erhalten eine Genius Wiedergabeliste, die Sie sofort anhören, sichern oder sogar aktualisieren können. Verlassen Sie sich also auf den Genius von iTunes, wenn Sie einen Mix wollen, auf den Sie selbst nicht gekommen wären.
 
Platz satt
Der iPod classic bietet mit seinen 160 GB Speicherkapazität Platz für bis zu 40.000 Songs, 200 Stunden Videos, 25.000 Fotos oder eine beliebige Kombination dieser Inhalte. Und mit bis zu 36 Stunden Batterielaufzeit beweist der iPod classic auch ganz schön viel Kondition.
 
Spaß auf Knopfdruck
Sie findeen immer ganz leicht genau das, was Sie sehen oder hören wollen. Mit dem Click Wheel können Sie mit ""Cover Flow"" Ihre Alben durchblättern, oder Sie stöbern über verschiedene Kategorien wie Wiedergabeliste, Künstler, Album oder Musikrichtung in Ihren Songs und Videos. Sie können natürlich auch nach einem bestimmten Titel oder Interpreten suchen. Lust auf einen neuen Mix? Klicken Sie einfach auf ""Zufällige Titel"".
 
Filme und Fernsehsendungen ansehen
Auf dem fantastischen 2,5"" Display kommen Videos richtig zur Geltung. Sie können im iTunes Store Filme kaufen oder ausleihen, Fernsehsendungen kaufen und Video-Podcasts laden. Dann können Sie alles mit Ihrem iPod classic synchronisieren und immer und überall ansehen.
 
 
Spiele auf dem iPod
Wenige Fingertipps, viele Stunden Spielspaß. Vortex, iQuiz und Klondike sind schon auf dem iPod classic vorinstalliert, im iTunes Store können Sie weitere dazukaufen, z. B. Cake Mania. Alle iPod Spiele sind speziell für die iPod Oberfläche optimiert.
 
Fotos zeigen
Ihre Fotos aus iPhoto auf einem Mac oder aus Adobe Photoshop Elements und Adobe Photoshop Album auf einem PC bekommen Sie mit iTunes auf den iPod classic. Sie können Diashows mit Musik und Übergängen auf dem iPod classic oder mit optional erhältlichen Apple Komponenten oder mit einem Composite-AV-Kabel sogar auf dem Fernseher zeigen.
 
Umweltverträglichkeit
Der iPod classic steht für das kontinuierliche Engagement von Apple in puncto Umweltschutz. Die folgenden Merkmale tragen zu einer geringen Umweltbelastung bei:
 
    Arsenfreies Displayglas
    Ohne bromhaltige Flammschutzmittel
    Display mit LED-Hintergrundbeleuchtung ohne Quecksilber
    Frei von PVC
    Recyclingfähiges Gehäuse aus Aluminium und Edelstahl
 
Produktbeschreibungen
Freiraum. Und zwar jede Menge. 160 GB sind wirklich eine ganze Menge Platz. Da lässt sich eine komplette Mediathek locker unterbringen und überallhin mitnehmen.
 
> Highlights
- Click Wheel
- Frequenzbereich: 20 Hz bis 20.000 Hz
- Weitere unterstützte Audioformate: Protected AAC (aus dem iTunes Store), MP3 VBR, Audible (Formate 2, 3, 4, Audible Enhanced Audio, AAX und AAX+), Apple Lossless und WAV
- Platz für bis zu 40.000 Songs im 128 KBit/Sek. AAC-Format
- Platz für bis zu 25.000 vom iPod anzeigbare Fotos
- Platz für bis zu 200 Stunden Videomaterial
- Speichert Daten auf einer USB-Festplatte
- Akkuladezeit: ca. 4 Std. (schnelles Laden auf 80%ige Kapazität in 2 Std.)
 
> Grundeigenschaften
- Breite: 103.5 mm
- Höhe: 61.8 mm
- Tiefe: 10.5 mm
- Gewicht: 140.0 g
- Farbe: Schwarz
 
> Wiedergabeformate Audio
- AAC
- MP3
- WAV
 
> Akku
- Akkutyp: Li-Ion
 
> Display
- Displaytechnologie: LCD
- 2.5- Display
- Bilddiagonale: 6.35 cm
- Auflösung Breite: 320 Pixel
- Auflösung Höhe: 240 Pixel
- Hintergrundbeleuchtung: ja
 
> Speicher
- Speicherkapazität 160 GB
 
> Anschlüsse
- USB
- USB-Standard 2.0
 
> Audio-Anschlüsse
- Headsetanschluss: 3,5 mm Klinke
- ipod-Anschluss via IPOD Connector
 
> Lieferumfang
- iPod classic
- Apple Earphones
- USB 2.0 Kabel
- Dock-Adapter
- Dokumentation
 
> Umweltverträglichkeit
Der iPod nano steht exemplarisch für das Engagement von Apple in puncto Umweltschutz. Die folgenden Merkmale des iPod nano tragen zu seiner geringeren Umweltbelastung bei:
- Arsenfreies Glas
- Frei von bromhaltigen Flammschutzmitteln
- Frei von Quecksilber
- Frei von PVC
- Besonders recyclingfähig
";2;False;0;;;Apple iPod Classic 120 GB schwarz;apple-ipod-classic-160-gb-silber;True;True;P-1410;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;249.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40124,2541319444;50;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000285-apple-ipod-classic-160-gb-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000284-apple-ipod-classic-160-gb-schwarz.jpg;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Apple iPod Nano 16 GB verschiedene Farben;Apple iPod Nano 16 GB;"
Apple iPod Nano 16 GB
 
 
Neues gebogenes Design, der dünnste iPod, den es je gab mit neuen Farben zu Auswahl
Die Bedieung optimiert: ein einziges Handschütteln und ein anderes Lied wird gespielt
Die neue Funktion ""Genius"" findet die Songs in Ihrer Mediathek, die besonders gut zusammenpassen, und erstellt daraus eine Genius Wiedergabeliste.
Viele Abspielformate: z.B. MP3, AAC, Apple Lossless, AIFF, WAV, H.264, MPEG-4
Lieferumfang: iPod Nano, Ohrhörer, USB 2.0 Kabel, Dock-Adapter, Dokumentation
 
Neues gebogenes Design, der dünnste iPod, den es je gab mit neuen Farben zu Auswahl
Die Bedieung optimiert: ein einziges Handschütteln und ein anderes Lied wird gespielt
Die neue Funktion ""Genius"" findet die Songs in Ihrer Mediathek, die besonders gut zusammenpassen, und erstellt daraus eine Genius Wiedergabeliste.
Viele Abspielformate: z.B. MP3, AAC, Apple Lossless, AIFF, WAV, H.264, MPEG-4
Lieferumfang: iPod Nano, Ohrhörer, USB 2.0 Kabel, Dock-Adapter, Dokumentation
 
Ein musikalisches Genie
Stell Dir vor, Du hörst einen Song. Toll wären jetzt andere Titel, die gut dazu passen. Was machst du? Ganz einfach: Du verwendest die neue Funktion ""Genius"". Diese findet die Songs in Deiner Mediathek, die gut zusammenpassen. Du erhältst eine Genius Wiedergabeliste, zusammengestellt von Deinem persönlichen, superintelligenten DJ.  
Musik schneller finden
Auch einen Song, den Du hören willst, findest Du jetzt viel einfacher. Du kannst Deine Alben mit Cover Flow anzeigen oder hältst einfach die mittlere Taste gedrückt und blätterst in Deinen Alben oder Interpreten. Den gewünschten Song gefunden? Einmal auf die mittlere Taste gedrückt, und schon hast Du ihn zur aktuellen Wiedergabeliste hinzugefügt. 
 
Aufdrehen und rumdrehen
Neige Deinen iPod nano in die Waagerechte, und schon kannst Du hören, sehen oder spielen wie nie zuvor. Deine Alben kannst Du mit Cover Flow durchblättern und siehst so viel mehr Alben oder Interpreten gleichzeitig auf dem Display.
 
Shake it, Baby!
Manchmal hat man einfach Lust auf eine kleine Überraschung. Darum kannst Du jetzt komplett dem Zufall überlassen, welches Lied Du als Nächstes hörst. Einfach den iPod nano kurz schütteln – und er springt zu irgendeinem anderen Song aus Deiner Musik-Bibliothek. Lass dich überraschen, was er Dir als Nächstes präsentiert.   
Spiel ab!
Jetzt kannst Du Dir mit Spielen die Zeit vertreiben, die ganz speziell auf den iPod nano und den Beschleunigungssensor zugeschnitten sind. Sie reagieren auf Deine Bewegungen und wirken dadurch so überzeugend, dass sie fast schon süchtig machen können. In jedem Fall wirst Du begeistert sein. Bereits vorinstalliert ist Maze, wo Du Dich durch Neigen, Kippen und allerlei andere Bewegungen durch riesige Labyrinthe manövrieren musst. Im iTunes Store stehen natürlich noch viele weitere Spiele zur Auswahl.
 
Sogar Deine Fotos rocken
Jetzt kannst Du gleich hunderte von Fotos aus der Tasche zaubern und überall vorführen. Senkrecht gehalten zeigt der iPod nano Deine Fotos im Hochformat an, wenn Du ihn um 90 Grad drehst, wechseln auch die Fotos ins Querformat. Die Fotos wirken in ihrem richtigen Größen- und Seitenverhältnis auf dem brillanten Display mit 320 x 240 Pixeln einfach hervorragend. 
Der größte kleine Bildschirm der Welt
Filme, Fernsehsendungen und Videos auf dem iPod nano anzusehen, ist das pure Vergnügen. Die hochauflösende Anzeige wirkt auf dem kristallklaren 2"" Breitbild-Display besonders brillant und lebendig. So hast Du mit dem iPod nano Dein eigenes Kino im Taschenformat immer dabei.  
 
Produktbeschreibungen
Flach, flacher, am flachsten mit nur 6,2mm bringt der iPod nano, in leuchtenden Farben, neuen Schwung ins Leben.
Mit brilianterem Display, höherer Speicherkapazität und noch längerer Batterielaufzeit schütteln Sie sich einfach durch Ihre Mediathek.
Leistungsmerkmale
- Verschieden Menüs: Musik, Fernsehsendungen, Videos, Hörbücher, Podcasts, Diashows, Spiele
- Geschwungenen Aluminium-Design mit gewölbtem Glas
- HxBxT: 90,7 x 38,7 x 6,2 mm
- Gewicht: 36,8 g
Lieferumfang
- iPod nano
- Ohrhörer
- USB 2.0-Kabel
- Dock-Adapter
- Dokumentation
Display
- 2- Farb-LCD mit LED-Hintergrundbeleuchtung
- 320 x 240 Pixel
Kapazität
- 8 GB Flash-Laufwerk1 für bis zu 2.000 Songs, 7.000 Fotos, 8 Std. Videomaterial
Batterie
- Integrierte, wiederaufladbare Lithium-Ionen-Batterie
- Musikwiedergabe: bis zu 24 Stunden bei voller Ladung
- Videowiedergabe: bis zu 4 Stunden bei voller Ladung
Audio
- Unterbrechungsfreie Wiedergabe
- Frequenzbereich: 20 Hz bis 20.000 Hz
- Unterstützte Audioformate: AAC, Protected AAC, MP3, MP3 VBR, Audible, Apple Lossless, AIFF und WAV
Systemvoraussetzungen
- USB 2.0-Anschluss
- mind. Mac OS X 10.4.11 bzw. mind. Windows Vista oder Windows XP Home oder Professional
- mind. iTunes 8  

 
 
 
";2;False;0;;;Apple iPod Nano 16 GB;apple-ipod-nano-16-gb-verschiedene-farben;True;True;P-1370;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;159.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40123,68375;47;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000075-apple-ipod-nano-8-gb-verschiedene-farben.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000076-apple-ipod-nano-8-gb-verschiedene-farben.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000077-apple-ipod-nano-8-gb-verschiedene-farben.jpg;1;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Acer Aspire 1810TZ-412G32n rot 29,5 cm (11,6 Zoll) Notebook;4 GB, 17 Zoll, 400 GB, Intel, 3;"
Aspire 1810T:
Das Aspire 1810T bietet die perfekte Balance aus unabhängiger Mobilität und flexibler Anwendung. Dieses handliche 29,46cm (11,6"") Notebook ist weniger als 1"" schmal, wartet aber auf mit einer vollausgestatteten Tastatur, HD Audio/Visual Unterhaltung und bis zu 8 Stunden mobiler Energie. Zusätzlich können Sie unter drei angesagten Farben auswählen: rubinrot, diamantschwarz und saphirblau.
 
 Kompaktes Design, excellente Anwendung
Dieses Notebook wiegt nur 1,35kg, so daß Sie es mühelos überall mitführen können. Mit der Acer Fine Tip Tastatur können Sie auch auf die übliche Notebook Nutzung zugreifen, dank der fortschrittlichen Kontrolle ohne Maus über das multifunktionale Touchpad.
 
8 Stunden Batterielaufzeit
Das Aspire 1810T ist mit einem Niedrig_Volt-Prozessor (ULV) versehen, der weniger Energie verbraucht und Sie von Ihrem Stromanschluß unabhängig macht. Einmal aufladen und Sie haben es von morgens bis abends zur Verfügung.
 
HD Erfahrung auf dem Vormarsch
Erleben Sie grandiose visuelle Effekte, brillant in Farbe und Bild, via 3D Grafik und einem 16:9 Bildschirm. Der integrierte HDMI Port ermöglicht Ihnen auch den leichten Anschluß an periphere Displays. Was den Klang angeht, erhalten Sie die optimierte 2. Generation des Dolby Sound Room für eine Tonerfahrung über viele Kanäle, zu empfangen über ein simples Paar Kopfhörer.
 
Auf den Punkt gekühlt
Die Acer ComfyTouch Technologie nutzt das innovative Design, um den Prozessor und das Gehäuse luftzukühlen. Auch wenn Sie das Notebook rund um die Uhr in Betrieb haben, bleibt es stets bei optimaler Temperatur.
 

Umweltbewußtsein als Motiv
Nehmen Sie die Energieersparnis wahr, ob unterwegs oder zuhause. In der Anwendung braucht das Aspire 1810T bis zu 40% weniger Strom als handelsübliche Notebooks.
 
 Nutzen Sie die Vorteile der mobilen Welt und schreiben Sie E-Mails oder chatten Sie mit Ihren Lieben, wo auch immer Sie gerade sind. Mit der erweiterten Netzwerkverbindung Wi-Fi CERTIFIED™ können Sie sich problemlos auf eine große Zahl von Verbindungen überall auf der Welt verlassen. Sie müssen sich an ein LAN anschließen? Kein Problem! Der Gigabit-Ethernet-Port garantiert eine ultraschnelle Verbindung.
 
 Die Acer Crystal Eye Webcam mit verbesserter Bilderfassung garantiert auch bei nicht optimaler Beleuchtung ein klares Bild bei Video-Chats und Webkonferenzen.
 
 HD-Ready (engl. „Bereit für HD“) ist ein von der der EICTA geschaffenes Label für Geräte (z.B.: Notebooks) die hochauflösendes Fernsehen (High Definition Television (HDTV)) wiedergeben können. Mindestvorsausetzungen für dieses Label sind unter anderem eine native 16:9-Auflösung von wenigstens 720 Zeilen, mindestens ein digitaler Eingang (DVI-D/-I oder HDMI), und eine Auflösung von 1280 × 720 Pixeln (Vollbilder) bzw. 1920 × 1080 Pixeln (Halbbilder). Ein Gerät das diesen Anforderungen gerecht wird kann hochauflösendes Fernsehen wiedergeben und verspricht ein gestochen scharfes Bilderlebnis.
 
";2;False;0;;;"Acer Aspire Timeline 1810TZ 11.6 Zoll Notebook ";acer-aspire-1810tz-412g32n-rot-295-cm-116-zoll-notebook;True;True;P-0830;;;False;0;False;;False;False;0;False;0;1;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;1;9999;False;False;0;1;1;0;False;1;10000;;False;False;False;False;547.9000;0.0000;0.0000;499.0000;41640;41820,9999884259;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40121,6691898148;"5;2095";37;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000527-acer-aspire-1810tz-412g32n-rot-295-cm-116-zoll-notebook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000528-acer-aspire-1810tz-412g32n-rot-295-cm-116-zoll-notebook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000529-acer-aspire-1810tz-412g32n-rot-295-cm-116-zoll-notebook.jpg;2;;True;ml;2.0000;1;;False;False;False;;;;;False;;;;;; +5;0;True;Canon PIXMA MP640 Multifunktionsgerät 3 in 1;"Canon PIXMA MP640 Multifunktionsgerät ";"
Canon PIXMA MP640 Multifunktionsgerät
 
 
3 in 1, Drucken, Kopieren, Scannen
 
 
Der PIXMA MP640 ist ein Multifunktionssystem der Spitzenklasse für exzellenten Fotodruck, schnellen Dokumentendruck und mit vielfältigen Scan- und Kopierfunktionen.
Dank WiFi- und Ethernet-Unterstützung kann er in ein kabelgebundenes und kabelloses Netzwerk integriert werden.

Multifunktionssystem: Fotodrucker, Farbscanner und Farbkopierer
Druckgeschwindigkeit: ca. 9,2 (SW) bzw. 8,1 (Farbe) ISO-Seiten/Min; einzelne Tintentanks
ca. 20 Sek. für den druck eines 10 x 15 cm Randlosprint
Automatischer Duplexdruck, doppelte Papierzufuhr und DVD/CD-Druck
Lieferumfang: PIXMA MP640, Netzkabel, Druckkopf, Tintentanks, DVD/CD-Halter, Kurzanleitung, CD mit Installations-Software und Benutzerhandbuch, Garantiekarte,
Druckmedien-Broschüre, Fotoglanzpapier Plus II PP-201, MP-101 zur Druckkopfausrichtung
";2;False;0;;;"Canon PIXMA MP640 ";canon-pixma-mp640-multifunktionsgeraet-3-in-1;True;True;P-2220;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;219.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40120,6418055556;22;25;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000523-canon-pixma-mp640-multifunktionsgerat-3-in-1.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000524-canon-pixma-mp640-multifunktionsgerat-3-in-1.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000525-canon-pixma-mp640-multifunktionsgerat-3-in-1.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Trekstor DataStation pocket x.u s ";Trekstor DataStation pocket x.u s 250 GB;"
Trekstor DataStation pocket x.u s 250 GB
 
 
Externe 2.5 Zoll Festplatte
Exklusives Aluminiumgehäuse für optimale Kühlung der Festplatte
Speichergröße 250 GB
Geeignet für das neue Windows® Vista
Lieferumfang: Festplatte, Nero BackItUp 2 Essentials, Software- / Treiber-CD, USB 2.0-Y-Anschlusskabel, Kurzanleitung, Transportetui
";2;False;0;;;"Trekstor DataStation pocket x.u s ";trekstor-datastation-pocket-xu-s;True;True;P-2640;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;89.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40120,6286921296;15;2;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000522-trekstor-datastation-pocket-xu-s.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Canon Digital IXUS 100 IS Digitalkamera silber;"Canon Digital IXUS 100 IS Digitalkamera silber ";"

Canon Digital IXUS 100 IS Digitalkamera silber

12 Megapixel, 3-fach opt. Zoom, 2,5"" Display, HDMI, SLIM
 
Die Digital Ixus 100 IS präsentiert sich im atemberaubend-exquisiten, nur 18,4 Millimeter flachen Edelstahlgehäuse. Sie ist in den vier Farben Silber, Schwarz, Gold und Rot erhältlich.

Ob großformatige Fotoprints oder gezielte Ausschnittvergrößerungen: Die hohe Auflösung von 12,1 Megapixeln sorgt für eine überzeugende Detailwiedergabe.
 
Für hohe Geschwindigkeit und exzellente Bildqualität mit brillanten Farben und minimiertem Bildrauschen steht der aktuelle Canon-Bildprozessor DIGIC 4.
12,1 Megapixel Sensor
3-fach optisches Zoom
Großes hochauflösendes 2,5 Zoll PureColor LCD II
Superschlank; HD-Movie und HDMI-Anschluß ¿ mehr Details im Film
 
Lieferumfang:
Digital IXUS 100 IS, Trageriemen, Akku, Akku-Ladegerät, USB-Kabel, Video-Kabel
";2;False;0;;;"Canon Digital IXUS 100 IS Digitalkamera ";canon-digital-ixus-100-is-digitalkamera-silber;True;True;P-1730;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;199.0000;199.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40119,9167824074;"56;2095";25;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000514-canon-digital-ixus-100-is-digitalkamera-silber.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000515-canon-digital-ixus-100-is-digitalkamera-silber.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000516-canon-digital-ixus-100-is-digitalkamera-silber.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Samsung N130-@nyNet 10,1 Zoll Netbook ";5 GB, 16 Zoll, 500 GB, AMD, 4;"
Samsung N130-@nyNet 10.1 Zoll Netbook  schwarz
 
Intel Atom N270 1.6GHz, 1GB RAM, 160GB HDD, Intel GMA 950, , Win 7 Starter
 
Mit dem N130 präsentiert Samsung Electronics ein preisgünstiges und leistungsstarkes Netbook der N-Serie. Ultraleicht und funktional arbeitet das N130 mit aktuellster Samsung Technologie und überzeugt durch Qualität, Design und Performance auf hohem Niveau. Das 1,26 kg leichte Netbook ist mit einem spiegelfreien 10,1-Zoll-Non-Gloss-Display ausgestattet. Mit einer Laufzeit von bis zu 6,5 Stunden gehört es zu den Langläufern im Netbook-Markt.
 
Flaches und elegantes Gehäuse-Design
Das N130 mit hochwertigen Komponenten und Materialien steckt in einem flachen, eleganten Design-Gehäuse. Mit seiner umfangreichen Funktionalität und gerade einmal 1,26 kg ist das N130 das leichteste Gerät seiner Klasse und bietet damit Mobilität auf höchstem Niveau.
 
Optimale Mobilität durch geringen Stromverbrauch
Das 10,1-Zoll-Non-Gloss-Display des N130 ist extrem energieeffizient und brilliert mit einem scharfen und hellen Bild ohne Spiegelungen sogar bei extremer Sonneneinstrahlung. Der geringe Stromverbrauch garantiert optimale Mobilität durch Samsungs führende Lithium-Ionen-Akku-Technik und ermöglicht eine außergewöhnliche Laufzeit von bis zu 6,5 Stunden.
 
Immer in Verbindung - mit WLAN
Schnellen Zugriff auf Internet und andere Inhalte gewährleistet das Netbook via 802.11b/g/n WLAN - jederzeit und überall. Darüber hinaus ist das Netbook mit einem eingebauten Mikrofon und Kopfhöreranschluss - beispielsweise für VoIP-Telefonie - ausgestattet. Mit drei USB 2.0-Anschlüssen und einem 3-in-1-Kartenleser erlaubt das N130 die Wahl zwischen zahlreichen Datenaustausch-Optionen. So lassen sich Informationen, Bilder, Musiktitel und Filme mit allen modernen Peripheriegeräten wie Kameras, externen Festplatten oder Audio/Video-Geräten blitzschnell austauschen. 
";2;False;0;;;"Samsung N130@nynet-N270BN 10.1 Zoll Netbook ";samsung-n130-nynet-101-zoll-netbook;True;True;P-0810;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;284.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40116,2153125;5;5;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000307-samsung-n130-nynet-101-zoll-netbook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000308-samsung-n130-nynet-101-zoll-netbook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000309-samsung-n130-nynet-101-zoll-netbook.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Asus EEE PC 1005HA-M 10,1 Zoll Netbook ";2 GB, 16 Zoll, 350 GB, Tantel, 4;"
Asus EEE PC 1005HA-M 10,1 Zoll Netbook mit Windows 7 Starter weiß
 
 
Langläufer: Eee PC 1005HA. Mit dem Eee PC 1005HA hat ASUS ein stylisches Geräte im Portfolio, das sich durch ihre lange Akkulaufzeit und ein mattes, nicht spiegelndes Display auszeichnen. Der Eee PC 1005HA-M inklusive Intel Atom N270 Prozessor kommt auf eine Akkulaufzeit von 8,5 Stunden. Die Geräte arbeiten mit dem Microsoft Windows 7 Betriebssystem und sind dadurch besonders intuitiv und komfortabel zu bedienen.
 
Das Betriebssystem Microsoft Windows 7
Mit Windows 7 stellt Microsoft ein Betriebssystem vor, das sich durch eine leichte Bedienung und einen ressourcensparenden Umgang mit der Hardware auszeichnet. Selbst auf Rechnern mit begrenzter Prozessorpower läuft das Betriebssystem mühelos. So benötigt der PC nur noch wenige Augenblicke zum Hochfahren und auf der übersichtlichen Taskleiste lassen sich anhand von Symbolen schnell die passenden Files erkennen. Spielend leicht wird auch die Verwaltung von Filmen, Bildern und Videos. Mithilfe der Bibliotheken lassen sich diese schnell organisieren. Und in punkto Sicherheit bringt das Betriebssystem einiges mit. Darunter die Benutzerkontensteuerung, die sich individuell konfigurieren lässt. 
 
Ehe PC 1005HA-M: Klasse Leistung zu unschlagbarem Preis
Der Eee PC 1005HA-M unterscheidet sich von seinem großen Bruder durch Prozessor, Akkukapazität sowie durch die integrierten Wireless Funktionen. Ausgestattet mit einem Intel Atom N270 Prozessor, einem 4400 mAh 6 Zellen Akku für bis zu 8,5 Stunden Laufzeit, WLAN 802.11n Standard sowie weiteren Top Merkmalen, überzeugt der Eee PC 1005HA-M zu einem unschlagbaren Preis.
 
Eee PC 1005HA-M: Funktionalität meets Design
Mit dem kompakten Eee PC 1005HA-M trägt ASUS seinem Anspruch, in den Produkten höchste Funktionalität mit formvollendetem Design zu verbinden, ein weiteres Mal Rechnung. So besticht der Eee PC durch sein elegantes und gleichzeitig unempfindliches Gehäuse, das mit klaren Linien und nach unten schmaler zulaufenden Kanten dem schlanken Design einer Muschel nachempfunden ist. 
  
Aber auch das Innenleben der Kleinen kommt ganz groß raus. Als gewohnt kontaktfreudig erweisen sich die Neulinge dank VGA Port für den Anschluss eines Monitors sowie drei USB 2.0 Schnittstellen, um Maus, Tastatur oder Digicam anzuschließen. Wer Bilder direkt von der SD oder MMC Speicherkarte auf den Eee PC übertragen möchte, nutzt den integrierten Kartenleser. Für das Speichern der Fotos stehen bei den Modellen eine 160 GB S-ATA Festplatte zur Verfügung. Die Modelle sind - wie alle Eee Familienmitglieder - ausgesprochen einfach zu bedienen. Das 10 Zoll WSVGA Display mit stromsparender LED-Hintergrundbeleuchtung sowie die große Tastatur, die zu 92% einer Standard Notebooktastatur entspricht, gewähren zusätzlichen Komfort. Für Chats oder Videokonferenzen hat ASUS die Minis zudem mit einer 1.3 Megapixel Web-/Videokamera sowie einem Mikrofon ausgestattet.
";2;False;0;;;"Asus EEE PC 1005HA-M 10,1 Zoll Netbook ";asus-eee-pc-1005ha-m-101-zoll-netbook;True;True;P-0800;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;291.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40115,7052199074;5;37;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000300-asus-eee-pc-1005ha-m-101-zoll-netbook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000301-asus-eee-pc-1005ha-m-101-zoll-netbook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000302-asus-eee-pc-1005ha-m-101-zoll-netbook.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Trekstor DataStation maxi g.u 1,5 TB ";"Trekstor DataStation maxi g.u externe Festplatte 1,5 TB ";"

Trekstor DataStation maxi g.u Externe Festplatte 1,5 TB

 
 
USB 2.0 inkl. Nero BackItUp 2 Essentials
 
 
 
Optimale Speicherplatzerweiterung
Die DataStation maxi g.u ist die perfekte Lösung für das
tägliche Backup oder die Speicherplatzerweiterung Ihres PCs.
Die externe 3,5“ Festplatte bietet ausreichend Platz
zum Speichern und Archivieren der heimischen Musik-
und Videosammlung, digitaler Fotos oder anderer Dateien. 
 Schnell und bedienungsfreundlich
Mit dem Hi-Speed USB 2.0 Anschluss bietet die
DataStation maxi g.u einen schnellen Datentransfer.
Die Festplatte ist zudem bereits vorformatiert und
ohne Treiber sofort betriebsbereit.
Unterstützt werden alle gängigen
Dateisysteme von Windows®, Linux® und Mac® OS X,
sowie die Betriebssysteme Microsoft
Windows® 2000 / XP/ Vista, Mac® OS X ab 10.3 und Linux® ab Kernel 2.6.x.
Die Festplatte wird über das mitgelieferte Netzteil mit Strom versorgt. 
Der Ein-/Ausschalter am Festplattengehäuse verhindert überflüssigen Stromverbrauch. 
Exklusives Aluminiumgehäuse
Das exklusive Aluminiumgehäuse der DataStation maxi g.u
sorgt für die optimale Kühlung der Festplatte,
so kommt die externe Festplatte
ohne Lüfter aus und ist leise während des Betriebs 
Inklusive Nero Software „BackItUp2 Essentials“
Die ebenfalls im Lieferumfang enthaltene
Nero Software rundet das Bild der mobilen, externen Festplatte perfekt ab.
Mit Nero BackItUp2 Essentials können Sie Backups Ihrer Daten sehr einfach planen.
So können einzelne Dateien oder ganze Laufwerke gesichert werden.
Um die Datenmenge gering zu halten, komprimiert die Software die Backups direkt „on the fly“.
Auf Wunsch lassen sich die gesicherten Daten auch per Passwortschutz vor unbefugtem Zugriff schützen.
";2;False;0;;;"Trekstor DataStation maxi g.u-externe Festplatte 1,5 TB ";trekstor-datastation-maxi-gu-15-tb;True;True;P-2630;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;139.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40101,7793981481;15;2;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000129-trekstor-datastation-maxi-gu-1tb.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"NAVIGON 2410 Navigationssystem inkl. TMC ";"NAVIGON 2410 Navigationssystem inkl. TMC ";"

NAVIGON 2410 Navigationssystem inkl. TMC

 
 
3,5"" Display, EU Kartenmaterial mit 40 Ländern, Fußgängernavigation im Hochformat
 
 
Fußgänger-Navigation
bringt Sie ohne Umwege ans Ziel, auch wenn Sie mal nicht im Auto unterwegs sind.
So können Sie z. B. unbekannte Städte ganz gezielt erkunden und finden auch die verstecktesten Plätze und Sehenswürdigkeiten.
Dabei halten Sie Ihr NAVIGON übrigens ganz bequem im Hochformat in einer Hand – und haben so die andere jederzeit frei.
 
NAVIGON Zielgerade
navigiert Sie nach dem Parken die letzten Meter zu Ihrem eigentlichen Ziel. Denn: Nicht vor jedem geplanten Ziel ist auch ein Parkplatz für Ihr Fahrzeug.
Deshalb lotst Ihr NAVIGON Sie sicher auf dem letzten Stück zu Fuß. Und findet auf dem Rückweg auch Ihr Auto für Sie wieder.
 
E-Kompass
Großstädte können auch zu Fuß sehr unübersichtlich sein. Damit Sie nicht mit den Himmelsrichtungen durcheinander kommen, unterstützt Sie im Fußgängermodus ein elektronischer Kompass.
So wissen Sie sofort, ob Sie nach links, rechts, oben oder unten laufen müssen. Beziehungsweise nach Westen, Osten, Norden oder Süden.
 
Clever Parking
hilft Ihnen bei der Parkplatzsuche. Kurz vor Ihrem Ziel zeigt Ihnen Clever Parking Parkplätze in der näheren Umgebung an.
In Deutschland, Österreich, Schweiz und Luxemburg werden Sie sogar über Parkgebühren und Öffnungszeiten informiert. So vermeiden Sie langes Suchen und sparen dabei Geld.
 
NAVIGON MyRoutes
Je nachdem, welcher Fahrertyp Sie sind, empfiehlt Ihnen NAVIGON MyRoutes die beste Route – zugeschnitten auf Ihren persönlichen Fahrstil, den Wochentag und die Tageszeit.
Darüber hinaus zeigt Ihnen Ihr NAVIGON bis zu zwei weitere Routen. Das schafft Transparenz. Sie entscheiden, ob Sie unserer Empfehlung folgen oder eine der Alternativen wählen.
 
TMC-Routeninfo
zeigt Ihnen im Fall einer Staumeldung eine Alternativroute mit aktualisierter Entfernung und Ankunftszeit.
Sie entscheiden, ob eine Umfahrung in Ihrem Fall sinnvoll ist oder ob Sie die ursprüngliche Route beibehalten wollen.
 
Lieferumfang
NAVIGON 2410, Kurzanleitung, KfZ-Ladekabel mit integrierter TMC Antenne, KfZ Halterung, USB-Kabel, Europa Kartenmaterial
";2;False;0;;;"NAVIGON 2410 Navigationssystem inkl. TMC ";navigon-2410-navigationssystem-inkl-tmc;True;True;P-2160;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;169.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40097,6045833333;68;14;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000299-navigon-2410-navigationssystem-inkl-tmc.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Adobe Premiere Elements 8;Adobe Premiere Elements 8 deutsch WIN;"

Adobe Premiere Elements 8 deutsch WIN


Mit Adobe® Premiere® Elements 8 erstellen Sie ohne Aufwand erstklassige Videos, die Sie mit professionellen Effekten bereichern und auf nahezu jedem Medium präsentieren können.
Dank eines leistungsfähigen und bedienungsfreundlichen Organizer behalten Sie den Überblick über Ihre Videos und Fotos.
 
Arbeiten Sie wie die Profis, indem Sie beispielsweise Grafiken und Effekte einfügen, die sich mit den zugehörigen Objekten zusammen bewegen.
Vielseitigkeit und Benutzerfreundlichkeit
Filmproduktion in wenigen Schritten
Filmerstellung per Drag-and-Drop
Zentrale Umgebung für Bearbeitung und Vorschau
Professionelle Spezialeffekte und Überblendungen
Aufwertung von Videos mit Musik
 
Systemanforderungen:
Prozessor mit 2 GHz und SSE2-Unterstützung; für HD oder Blu-ray: Prozessor mit 3 GHz; für AVCHD: Dual-Core-Prozessor
 
Microsoft® Windows® XP mit Service Pack 2, Windows Media Center, Windows Vista® oder Windows 7
Für Windows XP: 512 MB RAM (2 GB für HD-Bearbeitung einschließlich HDV, AVCHD oder Blu-ray)
Für Windows Vista and Windows 7: (1 GB RAM (2 GB für HD-Bearbeitung einschließlich HDV, AVCHD oder Blu-ray)
4,5 GB freier Festplattenspeicher
Farbmonitor mit 16-Bit-Grafikkarte
1024 x 768 Punkt Monitorauflösung mit 96 dpi oder geringer
Mit Microsoft DirectX 9 oder 10 kompatibler Sound- und Grafikkartentreiber
DVD-ROM-Laufwerk (kompatibler DVD-Brenner für die Erstellung von DVDs, kompatibler Blu-ray-Brenner für die Erstellung von Blu-ray Discs erforderlich)
 
";2;False;0;;;Adobe Premiere Elements 8;adobe-premiere-elements-8;True;False;P-3030;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;9200;False;False;0;1;1;0;False;1;10000;;False;False;False;False;112.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40097,5865856481;31;20;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000297-adobe-premiere-elements-8.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000298-adobe-premiere-elements-8.jpg;;2;;True;ml;1.0000;1;;False;False;False;;;;;False;;;;;; +5;0;True;Adobe Photoshop Elements 8;Adobe Photoshop Elements 8 deutsch WIN;"

Adobe Photoshop Elements 8 deutsch WIN

 

Adobe® Photoshop® Elements 8 ist die ideale Kombination aus Leistungsfähigkeit und Benutzerfreundlichkeit.
Verwalten Sie Ihre Bilder und Videos bequem zentral, machen Sie aus alltäglichen Motiven eindrucksvolle Kunstwerke, und gestalten Sie unverwechselbare Kreationen für Print und Web.
Jetzt können Sie perfekt ausgeleuchtete Bilder erstellen oder mit verschiedenen Bildgrößen experimentieren, ohne dass Verzerrungseffekte auftreten. Mit den erweiterten Suchfunktionen lassen sich Bilder wahlweise nach Qualität oder nach Motiv sortieren.

Vielseitigkeit und Benutzerfreundlichkeit
Praktischer Medien-Manager
Sekundenschnell retuschieren
Intuitive Anpassung von Farbe und Belichtung
Praktische Hilfestellungen
Herausragende Ergebnisse
Gelungene Präsentation im Web
Effiziente Umsetzung kreativer Ideen
 
Systemanforderungen:
Prozessor mit mindestens 1,6 GHz
Microsoft® Windows® XP mit Service Pack 2 oder 3, Windows Vista® oder Windows 7
1 GB RAM
2 GB freier Festplattenspeicher
Farbmonitor mit 16-Bit-Grafikkarte
1024 x 576 Punkt Monitorauflösung mit 96 dpi oder geringer
Mit Microsoft DirectX 9 kompatibler Grafikkartentreiber
DVD-ROM-Laufwerk
 
";2;False;0;;;Adobe Photoshop Elements 8;adobe-photoshop-elements-8;True;False;P-3020;;;False;0;False;;False;False;0;False;0;1;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;109.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40097,5787731481;31;20;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000295-adobe-photoshop-elements-8.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000296-adobe-photoshop-elements-8.jpg;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Garmin nüvi 255T Navigationssystem Europa ";"Garmin nüvi 255T Navigationssystem Europa inkl. TMC ";"
Garmin nüvi 255T Navigationssystem Europa inkl. TMC
 

3,5"" Touchscreen Display, PhotoNavigation, MicroSD-Kartenslot und ecoRoute 
 
Bedienerfreundliches Einsteigernavigationsgerät mit elegantem, ultra-schlankem Design und brillantem 3,5 (8,9cm Bilddiagonale)
Touchscreen Display + TMC Verkehrsfunkempfänger
Kartenmaterial für 40 Länder in West- und Osteuropa intern vorinstalliert ecoRoute:
reduziert den Kraftstoffverbrauch, CO2-Emissionen und schont die Umwelt, spart bares Geld und füllt die Reisekasse auf.
PhotoNavigation mit Garmin Connect: Sie können Sehenswürdigkeiten und Bilder herunterladen und als Ziel auswählen
Lieferumfang: Garmin nüvi 255T mit Kartenmaterial Europa, TMC Verkehrsfunkempfänger,
Saugnapfhalterung für die Windschutzscheibe, Armaturenhalterung, Schnellstartanleitung, KFZ-Anschlusskabel
 
";2;False;0;;;"Garmin nüvi 255T Navigationssystem Europa ";garmin-nuevi-255t-navigationssystem-europa;True;True;P-2090;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;129.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40096,6680208333;67;44;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000294-garmin-nuvi-255t-navigationssystem-europa.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Logitech Webcam C200 ";"Logitech Webcam C200 ";"
Sie suchen nach einem Basispaket für eine einfache, klare Videokommunikation? Die preisgünstige Logitech
Webcam C200 stellt Ihnen alle Funktionen zur Verfügung, die Sie für realitätsnahe Videogespräche benötigen. Sie bezahlen nicht für Zusatzfeatures, die Sie wahrscheinlich ohnehin nicht nutzen. Ihre Webkamera wird mit der Logitech Vid-Software geliefert, die Ihnen mit nur einem Mausklick das Führen von Videogesprächen ermöglicht – schnell, kostenlos, einfach. Der VGA-Sensor erfasst Ihre Live-Videobilder in natürlichen und realistischen Farben. Sie können auch Schnappschüsse machen, die per Software auf eine Auflösung von 1,3 Megapixeln hochgerechnet werden. Und das praktische eingebaute Mikrofon sorgt mit der Logitech RightSound- Technologie dafür, dass Ihre Stimme klar verständlich ist. Dank der Universalmonitorhalterung können Sie diese Webkamera problemlos an jedem Desktopmonitor oder Notebookrechner befestigen.
 

Seien Sie persönlich dabei - mit dem Basispaket für eine kostenlose und klare Videokommunikation
 
Ein Besuch bei Ihren Freunden und Verwandten in der Ferne ist ab sofort wesentlich einfacher. Mit der preiswerten Logitech Webcam C200 sind Sie nämlich direkt bei den Menschen, die Ihnen am Herzen liegen. Installieren Sie einfach Ihre Webkamera, und schon können Sie Ihr erstes Videogespräch führen. Dazu ist nur ein einfacher Mausklick erforderlich, wenn Sie die Vid-Software nutzen, die mit Ihrer Webkamera mitgeliefert wird. Plaudern Sie persönlich mit Ihren Enkeln in der Nachbarstadt – oder mit Ihrer besten Freundin am anderen Ende der Welt. Der VGA-Sensor sorgt dafür, dass Ihre Gesprächspartner Sie in ganz natürlichen Farben sehen. Und dank dem eingebauten Mikrofon mit der Logitech RightSound-Technologie, die störende Nebengeräusche herausfiltert, können sie jedes Wort aus Ihrem Mund deutlich verstehen. Wenn Sie ein praktisches Basispaket für Videogespräche suchen und auf komplizierte Zusatzfunktionen verzichten können, ist dies die richtige Webkamera für Sie.
 
Die wichtigsten Funktionen
 
Webkameras von Logitech - bessere Videoqualität kommt nicht von ungefähr
 
Sobald Sie Ihr erstes Videogespräch führen, wird Ihnen klar werden, warum Logitech die erste Wahl von Webkamera-Anwendern auf der ganzen Welt ist. Bei der Entwicklung jeder Webkamera ist das oberste Designziel von Logitech, eine erheblich klarere Bild- und Tonqualität als andere Webkameras zum gleichen Preis zur Verfügung zu stellen. Dabei geht es geht nicht nur um Features wie Qualität des Objektivs, Sensor-Auflösung und Software. Es geht viel mehr darum, wie alle diese Dinge ineinandergreifen, um Ihnen eine Videokommunikation mit mehr Komfort und Vergnügen zu ermöglichen.
   
Der VGA-Sensor zeigt Ihr wahres Ich
 
Nur weil Sie nicht so viel Geld ausgeben wollen, heißt das noch lange nicht, dass Sie auf Qualität verzichten müssen. Ihre Logitech-Webkamera bietet Ihnen Extras, die Sie bei einer so preisgünstigen Webkamera wahrscheinlich gar nicht erwarten würden. Dazu zählt ein Sensor, der Live-Videobilder mit echter VGA-Auflösung in realitätsnahen Farben aufnimmt. Keine grünlich-bleichen oder verschwommenen Gesichter. Ihre Gesprächspartner bekommen Ihr wahres, natürliches Ich zu sehen. 
Auflösung mit bis zu 1,3 Megapixeln – verschicken Sie brillante digitale Schnappschüsse
 
Sie möchten Ihre Webkamera auch noch anderweitig nutzen? Drücken Sie einfach auf den Schnappschussauslöser, um realitätsnahe Fotos aufzunehmen, die per Software auf 1,3 Megapixel hochgerechnet werden. Und da sich die Schnappschüsse schon auf Ihrem Rechner befinden, können Sie sie ganz einfach per E-Mail an Verwandte oder Freunde verschicken.   
 
Eingebautes Mikrofon mit geräuschdämpfender RightSound- Technologie
 
Sprechen Sie ganz natürlich, das eingebaute Mikrofon der Webkamera nimmt jedes Wort, jedes Lachen, jedes Flüstern auf. Die RightSound-Technologie filtert automatisch störende Hintergrundgeräusche heraus, sodass Sie Ihre Gespräche immer mit kristallklarer Tonqualität führen können. 
 
Vielseitige Universalhalterung für die Befestigung an jedem Desktop- oder Notebook-Rechner
 
Was das praktische Design anbetrifft, hat Logitech an alles gedacht. Die Webkamera lässt sich problemlos und sicher an LCD-Bildschirmen ebenso wie an ultraflachen Notebook-Monitoren befestigen. Die Halterung kann auch eingeklappt werden, sodass Sie die Kamera auf einer ebenen Oberfläche wie beispielsweise einem Regal über Ihrem Computer aufstellen können.   
 
Problemlose Videogespräche dank Unterstützung aller Instant-Messaging-Programme
 
 
Alles, was Sie für Videogespräche benötigen, ist die Webkamera, ein schneller Internet-Zugang und ein Videokommunikations-Programm. Wenn Sie Ihre Freunde und Verwandten schnell, einfach und kostenlos von Angesicht zu Angesicht sprechen wollen, empfehlen wir Ihnen Logitech Vid als Software der Wahl. Sie können aber auch andere IM-Programme vom Internet herunterladen. Im Gegensatz zu den Produkten manch anderer Anbieter funktionieren die Webkameras von Logitech mit allen Instant-Messaging-Programmen, die Sie nutzen und die Ihre Gesprächspartner verwenden. Sie können also ganz problemlos und ohne großen Aufwand Videogespräche führen.
 
Mit der Logitech Webcam C200 und kostenlosen Video-Anwendungen können Sie „persönlich vor Ort“ sein – in Ihrer Stadt oder an jedem anderen Fleck der Erde. 
 
 
";2;False;0;;;"Logitech Webcam C200 ";logitech-webcam-c200;True;True;P-2920;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;34.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40096,6475;"27;2095";11;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000290-logitech-webcam-c200.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000291-logitech-webcam-c200.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000292-logitech-webcam-c200.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Western Digital My Book 1 TB;"Western Digital BAAF0010HBK My Book Essential 1TB ";"
Western Digital BAAF0010HBK My Book Essential

1TB externe Festplatte 
 
Elegantes Design
Ihre gesamten Daten auf einen Blick und einfache Datei-Wiederherstellung
Passwortschutz und 256-bit Hardware basierte Verschlüsselung
Automatische, kontinuierliche Datensicherung für alle Computer in Ihrem Netzwerk
Lieferumfang: Western Digital My Book Essential 1TB externes Festplattenlaufwerk,
WD SmartWare-Software, USB-Kabel, Netzteil, Schnellanleitung
";2;False;0;;;"Western Digital My Book Essential Edition 1 TB ";western-digital-my-book-1-tb;True;True;P-2600;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;129.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40090,625150463;14;21;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000286-western-digital-my-book-1-tb.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Apple iPod Classic 160 GB schwarz;"Apple iPod Classic 160 GB schwarz ";"

Apple iPod Classic 160 GB schwarz

 
iPod classic: Freiraum -Und zwar jede Menge.
160 GB sind wirklich eine ganze Menge Platz. Da lässt sich eine komplette Mediathek locker unterbringen und überallhin mitnehmen.
 
Ein musikalisches Genie
Stellen Sie vor, Sie hören einen Song. Toll wären jetzt andere Titel, die gut dazu passen. Was machen Sie? Ganz einfach: Sie verwenden die neue Funktion ""Genius"". Diese findet die Songs in Ihrer Mediathek, die gut zusammenpassen. Sie erhalten eine Genius Wiedergabeliste, die Sie sofort anhören, sichern oder sogar aktualisieren können. Verlassen Sie sich also auf den Genius von iTunes, wenn Sie einen Mix wollen, auf den Sie selbst nicht gekommen wären.
 
Platz satt
Der iPod classic bietet mit seinen 160 GB Speicherkapazität Platz für bis zu 40.000 Songs, 200 Stunden Videos, 25.000 Fotos oder eine beliebige Kombination dieser Inhalte. Und mit bis zu 36 Stunden Batterielaufzeit beweist der iPod classic auch ganz schön viel Kondition.
 
Spaß auf Knopfdruck
Sie findeen immer ganz leicht genau das, was Sie sehen oder hören wollen. Mit dem Click Wheel können Sie mit ""Cover Flow"" Ihre Alben durchblättern, oder Sie stöbern über verschiedene Kategorien wie Wiedergabeliste, Künstler, Album oder Musikrichtung in Ihren Songs und Videos. Sie können natürlich auch nach einem bestimmten Titel oder Interpreten suchen. Lust auf einen neuen Mix? Klicken Sie einfach auf ""Zufällige Titel"".
 
Filme und Fernsehsendungen ansehen
Auf dem fantastischen 2,5"" Display kommen Videos richtig zur Geltung. Sie können im iTunes Store Filme kaufen oder ausleihen, Fernsehsendungen kaufen und Video-Podcasts laden. Dann können Sie alles mit Ihrem iPod classic synchronisieren und immer und überall ansehen.
 
 
Spiele auf dem iPod
Wenige Fingertipps, viele Stunden Spielspaß. Vortex, iQuiz und Klondike sind schon auf dem iPod classic vorinstalliert, im iTunes Store können Sie weitere dazukaufen, z. B. Cake Mania. Alle iPod Spiele sind speziell für die iPod Oberfläche optimiert.
 
Fotos zeigen
Ihre Fotos aus iPhoto auf einem Mac oder aus Adobe Photoshop Elements und Adobe Photoshop Album auf einem PC bekommen Sie mit iTunes auf den iPod classic. Sie können Diashows mit Musik und Übergängen auf dem iPod classic oder mit optional erhältlichen Apple Komponenten oder mit einem Composite-AV-Kabel sogar auf dem Fernseher zeigen.
 
Umweltverträglichkeit
Der iPod classic steht für das kontinuierliche Engagement von Apple in puncto Umweltschutz. Die folgenden Merkmale tragen zu einer geringen Umweltbelastung bei:
 
    Arsenfreies Displayglas
    Ohne bromhaltige Flammschutzmittel
    Display mit LED-Hintergrundbeleuchtung ohne Quecksilber
    Frei von PVC
    Recyclingfähiges Gehäuse aus Aluminium und Edelstahl
 
Produktbeschreibungen
Freiraum. Und zwar jede Menge. 160 GB sind wirklich eine ganze Menge Platz. Da lässt sich eine komplette Mediathek locker unterbringen und überallhin mitnehmen.
 
> Highlights
- Click Wheel
- Frequenzbereich: 20 Hz bis 20.000 Hz
- Weitere unterstützte Audioformate: Protected AAC (aus dem iTunes Store), MP3 VBR, Audible (Formate 2, 3, 4, Audible Enhanced Audio, AAX und AAX+), Apple Lossless und WAV
- Platz für bis zu 40.000 Songs im 128 KBit/Sek. AAC-Format
- Platz für bis zu 25.000 vom iPod anzeigbare Fotos
- Platz für bis zu 200 Stunden Videomaterial
- Speichert Daten auf einer USB-Festplatte
- Akkuladezeit: ca. 4 Std. (schnelles Laden auf 80%ige Kapazität in 2 Std.)
 
> Grundeigenschaften
- Breite: 103.5 mm
- Höhe: 61.8 mm
- Tiefe: 10.5 mm
- Gewicht: 140.0 g
- Farbe: Schwarz
 
> Wiedergabeformate Audio
- AAC
- MP3
- WAV
 
> Akku
- Akkutyp: Li-Ion
 
> Display
- Displaytechnologie: LCD
- 2.5- Display
- Bilddiagonale: 6.35 cm
- Auflösung Breite: 320 Pixel
- Auflösung Höhe: 240 Pixel
- Hintergrundbeleuchtung: ja
 
> Speicher
- Speicherkapazität 160 GB
 
> Anschlüsse
- USB
- USB-Standard 2.0
 
> Audio-Anschlüsse
- Headsetanschluss: 3,5 mm Klinke
- ipod-Anschluss via IPOD Connector
 
> Lieferumfang
- iPod classic
- Apple Earphones
- USB 2.0 Kabel
- Dock-Adapter
- Dokumentation
 
> Umweltverträglichkeit
Der iPod nano steht exemplarisch für das Engagement von Apple in puncto Umweltschutz. Die folgenden Merkmale des iPod nano tragen zu seiner geringeren Umweltbelastung bei:
- Arsenfreies Glas
- Frei von bromhaltigen Flammschutzmitteln
- Frei von Quecksilber
- Frei von PVC
- Besonders recyclingfähig
 
";2;False;0;;;Apple iPod Classic 120 GB schwarz;apple-ipod-classic-160-gb-schwarz;True;True;P-1400;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;239.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40089,850162037;50;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000284-apple-ipod-classic-160-gb-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000285-apple-ipod-classic-160-gb-schwarz.jpg;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Logitech MK300 schnurlose Tastatur + Maus schwarz ";"Logitech MK300 schnurlose Tastatur + Maus schwarz ";"

Logitech MK300 schnurlose Tastatur + Maus schwarz
 

 
Kabellose Technologie für eine schnelle und zuverlässige Verbindung, die sofort einsatzbereit ist
Sondertasten und programmierbare F-Tasten
Flüssigere und reaktionsschnellere Abtastung als herkömmliche optische Mäuse
Automatischer Energiesparmodus
 
Lieferumfang:
Logitech MK300 Tastatur schnurlos, Logitech MK300 Maus schnurlos, USB-Empfänger, Batterien vom Typ AA, Handbuch, CD mit Software.
";2;False;0;;;;logitech-mk300-schnurlose-tastatur-maus-schwarz;True;True;P-2800;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;49.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40081,7438194444;21;11;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000513-logitech-mk300-schnurlose-tastatur-maus-schwarz.jpg;;;1;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Samsung NC10 anyNet 10,2 Zoll Netbook;"Samsung NC10 anyNet 10,2 Zoll Netbook schwarz ";"
Samsung NC10 anyNet10,2"" Netbook

Intel Atom N270 1.6GHz, 1GB RAM, 160GB HDD, Intel GMA 950 XP Home
 
NC10-anyNet: Entwickelt für das ""mobile Leben"". Entwickelt für höchste Ansprüche in innovativem Design. Das ultrakompakte und leichte Gehäuse bietet eine Reihe von praktischen Features, die das mobile Leben vereinfachen. Brillante Technologie angepasst an das rasante und digitale Leben für noch mehr Mobilität.
 
Schlankes Design
Mit einem optimierten 10,2 Zoll Breitbild Display für ein makelloses visuelles Erlebnis, ist das schlanke NC10 lediglich 1,19 cm hoch und passt nahezu in alle Taschen. Das widerstandsfähige Gehäuse bietet ein Maximum an Tragekomfort und Verlässlichkeit sowie hochwertiger Ergonomie und Stil.
 
Videokonferenz
Ob Videokonferenzen oder Live Messaging - die integrierte 1,3 Megapixel Kamera lässt sie noch leichter mit Freunden, Familie und Kollegen in Kontakt bleiben. Die Kamera verbindet die Auflösung und die Bildqualität einer Fotokamera mit der nachhaltig hohen Bildfrequenz einer Videokamera.
 
Robustes Gehäuse, langlebig und verlässlich
Fühlen Sie sich sicher mit dem robusten Protect-o-Edge Gehäuse, das für Langlebigkeit und Verlässlichkeit steht. Eine aufwendige Serie von 54 Qualitätstests, die von schnellen Temperaturwechseln bis zu elektrischen Überspannungen reichen, gewährleistet neue Standards in Punkto Belastbarkeit und Ausdauer.
 
Antibakterielle Tastatur
Die SilverNano Technologie beschichtet die Tastatur mit nano-kleinen Silberionen, die das Überleben und die Neuentstehung von Bakterien verhindern. Innerhalb von 24 Stunden werden 99,9% aller Bakterien abgetötet und es entsteht eine hygienische Arbeitsatmosphäre.
 
Leichtgewicht
Als eines der weltweit leichtesten 10,2 Zoll Mini Notebooks seiner Klasse, mit einem Gewicht von nur 1,45 kg, ist das NC10 voll bepackt mit neuester Technologie und garantiert dabei maximale Mobilität und Leistung.
  
Vollständige Notebook-Tastatur
Die vollständige Notebook-Tastatur bietet optimalen Schreibkomfort. Ergonomisches Design und optimierte Tastenabstände machen das Arbeiten und Kommunizieren angenehmer und ermöglichen schnelleres sowie fehlerloses Schreiben.
 
Voll ausgestattet für einfachen Datenaustausch
Einfacher Datenaustausch dank einer Vielzahl an Anschlussmöglichkeiten, inklusive einem Kartenleser und drei USB-Anschlüssen, so dass Sie problemlos Bilder, Filme und Daten auf und von nahezu allen modernen Kameras, periphären oder audiovisuellen Geräten transferieren können.
";2;False;0;;;;samsung-nc10-anynet-102-zoll-netbook;True;True;P-0860;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;329.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40066,9226388889;6;5;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000511-samsung-nc10-anynet-102-zoll-netbook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000512-samsung-nc10-anynet-102-zoll-netbook.jpg;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Casio EXILIM EX-Z2 Digitalkamera schwarz;"Casio EXILIM EX-Z2 Digitalkamera schwarz ";"
Casio EXILIM EX-Z2 SR Digitalkamera schwarz
 
12 Megapixel, 3-fach opt. Zoom, 2,7"" Display


Die EX-Z2 versteckt in ihrem flachen Designgehäuse leistungsstarke 12,1 Megapixel.
Der CCD-Chip mit 12,1 Megapixel erlaubt nicht nur brillante Fotos zu machen, sondern auch Bildausschnitte zu bearbeiten, zu vergrößern und im Wunschformat auszudrucken – bei hervorragender Qualität und ohne Verlust von Bildinformationen.
 
12,0 Megapixel CCD-Chip
3fach optischer Zoom, 4fach digitaler Zoom
6,9 cm (2.7 Zoll) Wide Screen TFT- Farbdisplay
23 BEST SHOT Programme, Gesichtserkennung, Selbstauslöser, Speicherkartenslot für SD-/SDHC, MMC-/MMCplus und Eye-Fi Wireless Speicherkarten
 
Lieferumfang:
Digitalkamera, Akku, Ladegerät, USB-Kabel, AV-Kabel, Trageriemen, Grundlegende Referenz, CD-ROM
";2;False;0;;;"Casio EXILIM EX-Z2 SR Digitalkamera ";casio-exilim-ex-z2-digitalkamera-schwarz;True;True;P-1750;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;149.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40064,7887268519;"57;2095";9;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000499-casio-exilim-ex-z2-digitalkamera-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000500-casio-exilim-ex-z2-digitalkamera-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000501-casio-exilim-ex-z2-digitalkamera-schwarz.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Samsung Syncmaster P2250 21,5 Zoll TFT Monitor schwarz;"Samsung Syncmaster P2250 21,5 Zoll TFT Monitor schwarz ";"
Samsung Syncmaster P2250 21,5 Zoll TFT Monitor schwarz

DVI ,Kontrast 50000:1, 2ms Reaktionszeit

DieSyncMaster 50er Serie überzeugt mit schlichtem Design und moderner Technik.
Der elegant schmale Rahmen in Verbindung mit dem dezenten roten Farbverlauf macht diese Modelle zu einem echten Blickfang.
Das praktische 16:9-Format bietet eine Full HD Auflösung mit 1.920 x 1.080 Pixel.
Das sehr hohe dynamische Kontrastverhältnis von 50.000:1 und die schnelle Reaktionszeit von nur 2 ms (G/G) sorgen
stets für klare und detailreiche Bilder - auch bei schnell bewegten Bildinhalten.
Das praktische 16:9-Widescreen-Format ermöglicht ein noch angenehmeres Arbeiten bei gleichzeitiger Steigerung Ihrer Produktivität.
Das Breitbildformat entspricht dem natürlichen Sichtfeld des Betrachters. Somit haben Sie immer alles im Blick, ohne auf wichtige Informationen verzichten zu müssen.
Dieses SyncMaster Large Format Display verfügt über ein Full HD-Panel mit einer nativen Auflösung von 1.920 x 1.080 Pixel.
Somit können Bildinhalte im 1.080p-Format, der derzeit besten HD-Auflösung, wiedergegeben werden. 
Genießen Sie beste Bildqualität mit hoher Bildschärfe und Detailreichtum selbst in dunklen Szenen.
Mit einem dynamischen Kontrast von 50.000:1 werden Sie jedes Detail auf dem Bildschirm erkennen können.
Lieferumfang: Monitor, Signalkabel, Netzkabel, Treiber CD, Handbuch (CD)
";2;False;0;;;"Samsung Syncmaster P2250 21,5 Zoll ";samsung-syncmaster-p2250-215-zoll-tft-monitor-schwarz;True;True;P-2470;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;219.9000;219.9000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40048,6219907407;9;5;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000376-samsung-syncmaster-p2250-215-zoll-tft-monitor-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000377-samsung-syncmaster-p2250-215-zoll-tft-monitor-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000378-samsung-syncmaster-p2250-215-zoll-tft-monitor-schwarz.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Panasonic DMR EH 595 EG K DVD-/HDD-Rekorder 250 GB ";"Panasonic DMR EH 595 EG K DVD-/HDD-Rekorder 250 GB ";"

Panasonic DMR EH 595 EG K DVD-/HDD-Rekorder 250 GB

  
HDMI, DivX-zertifiziert, USB 2.0
 
  
Die Rekorder DMR-EH595 zeigen sich als wahre Alleskönner und zeichnen auf Festplatte oder DVD auf.
Sie verarbeiten alle gängigen DVD-Formate wie DVD-RW, -R (DL), DVD+RW/+R (DL) sowie DVD-RAM. Außerdem können CDs, CD-R/-RWs sowie MP3- und JPEG-Daten sowohl von DVD als auch CD abgespielt werden.
Die integrierte Festplatte erlaubt die Aufzeichnung von Fernsehprogrammen. Somit ist auch bei längerer Abwesenheit genügend Platz für die Lieblingsserie vorhanden.
Dank des integrierten, elektronischen Programmführers Gemstar Guide Plus+ erfolgen die Programmauswahl und Timerprogrammierung kinderleicht und intuitiv.
Die übersichtliche Darstellung des Fernsehprogramms bietet neben einer Genre-Auswahl zusätzlich eine gezielte Suche nach Stichworten.
So kann beispielsweise direkt nach Schauspielern, Themen oder Sportarten gesucht werden.
Neben dieser Funktion arbeiten die neuen Rekorder mit einer automatischen Kapitelerstellung bei der Aufzeichnung.
Dadurch können während der anschließenden Wiedergabe unerwünschte Programmsequenzen auf Knopfdruck übersprungen oder eine Szene blitzschnell gefunden werden.
Mit Pause Live TV kann zudem das laufende Fernsehprogramm jederzeit mit einem Druck auf die Pause-Taste angehalten und zu einem späteren Zeitpunkt weitergeschaut werden.
Dank Quick Start-Funktion sind die Rekorder innerhalb einer Sekunde einsatzbereit, so dass kein Film und keine Aufzeichnung verpasst werden.

Multiformat-DVD-Festplatten-Kombination
Intuitive Benutzerführung
Neben der Aufnahme des Fernsehprogramms überzeugen die neuen Rekorder als digitales Fotoalbum sowie Musik-Jukebox
Elektronische Programmführer Guide Plus+ mit Suchfunktion
Umfangreiche Anschlussmöglichkeiten
";2;False;0;;;Panasonic DMR EH 595 EG K;panasonic-dmr-eh-595-eg-k-dvd-hdd-rekorder-250-gb;True;True;P-1800;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;379.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40046,702650463;63;12;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000375-panasonic-dmr-eh-595-eg-k-dvd-hdd-rekorder-250-gb.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Garmin Freizeitguide Deutschland ";"Garmin Freizeitguide Deutschland ";"

Garmin Freizeitguide Deutschland

 
 
Wander- und Freizeitkarten von 21 Regionen 



Freizeit- und Wanderkarten von 21 Nationalparks und Freizeitregionen vom Bayrischen Wald bis zur Insel Rügen im Maßstab 1:25.000 (Auflistung der Regionen auf www.garmin.de)
Kompatibel mit allen aktuellen Garmin nüvi-Straßennavigationsgeräten und kartenfähigen Outdoor-GPS Geräten
Sonderziele (POIs) wie Freizeitparks, Schlösser, Burgen, Denkmäler, Museen, Zoos, Bäder und Thermen können direkt angesteuert werden
Micro SD Karte kann einfach in den Kartenslot eingeschoben werden - Installation oder Freischaltung entfällt
Lieferumfang: Micro SD Karte mit Freizeitguide Deutschland
";2;False;0;;;;garmin-freizeitguide-deutschland;True;True;P-2080;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;29.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40041,5175231481;"67;2095";44;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000364-garmin-freizeitguide-deutschland.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Garmin Nüvi 1490 Tpro Navigationssystem Europa ";"Garmin Nüvi 1490 Tpro Navigationssystem Europa ";"

Garmin Nüvi 1490 Tpro Navigationssystem Europa

 
 
 
5"" Touchscreen-Display, TMC Pro, ecoRoute, Fußgänger- und PhotoNavigation, Bluetooth
 
 
 
Mobile Navigation ohne Grenzen im Großformat, im ultra-flachem Design an die Bedürfnisse professioneller Anwender ausgerichtet
Übersichtliche und einfache Navigation im 5 Zoll Display mit Fahrspurassistent und 3D-Kreuzungsansicht,
TMC Pro Europa Premium Verkehrsfunkempfänger
Kartenmaterial für 41 Länder in West- und Osteuropa intern vorinstalliert;
Inklusive ecoRoute die Garmin Spritspar-Funktion und echter Fußgängernavigation mit optionalen CityXplorer Stadtplänen für Bus und Bahn
Lieferumfang: Garmin nüvi 1490Tpro mit Kartenmaterial Europa, KFZ-Anschlusskabel mit TMC Pro-Verkehrsfunkempfänger,
Saugnapfhalterung für die Windschutzscheibe, Armaturenhalterung, Schnellstartanleitung
";2;False;0;;;"Garmin Nüvi 1490Tpro Navigationssystem Europa ";garmin-nuevi-1490-tpro-navigationssystem-europa;True;True;P-2070;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;289.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40041,5110416667;67;44;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000363-garmin-nuvi-1490-tpro-navigationssystem-europa.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Garmin nüvi 255WT Navigationssystem Europa ";Garmin nüvi 255WT Navigationssystem Europa inklusive TMC;"

Garmin nüvi 255WT Navigationssystem Europa

inklusive TMC, 4,3"" Touchscreen Display, PhotoNavigation, SD-Kartenslot und ecoRoute
 
Bedienerfreundliches Einsteigernavigationsgerät mit elegantem, ultra-schlankem Design und brillantem 4,3“ großem Touchscreen Display + TMC Verkehrsfunkempfänger Kartenmaterial für 40 Länder in West- und Osteuropa intern vorinstalliert; ecoRoute: reduziert den Kraftstoffverbrauch, CO2-Emissionen und schont die Umwelt, spart bares Geld und füllt die Reisekasse auf. PhotoNavigation mit Garmin Connect: Sie können Sehenswürdigkeiten und Bilder herunterladen und als Ziel auswählen Lieferumfang: Garmin nüvi 255W mit Kartenmaterial Europa, + TMC Verkehrsfunkempfänger (=WT), Saugnapfhalterung für die Windschutzscheibe, Armaturenhalterung, Schnellstartanleitung, KFZ-Anschlusskabel
";2;False;0;;;"Garmin nüvi 255WT Navigationssystem Europa ";garmin-nuevi-255wt-navigationssystem-europa;True;True;P-2060;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;169.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40041,5046064815;67;44;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000362-garmin-nuvi-255wt-navigationssystem-europa.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Canon PowerShot SX200 IS ";Canon PowerShot SX200 IS;"

Canon PowerShot SX200 IS

12 Megapixel, 12-fach opt. Zoom, 3"" Display

Das neue Super-Zoom-Modell unter den Canon PowerShot-Digitalkameras zeigt große Stärke im kompakten Format:
28 Millimeter-Weitwinkelobjektiv, 12-fach optischen Zoom, DIGIC-4-Bildprozessor und starke 12,1 Megapixel machen die PowerShot SX200 IS zu einem idealen Reisebegleiter.
Für Spitzenqualität können Movieclips in High Definition mit 720p und 30 B/s aufgezeichnet und über die integrierte HDMI™-Schnittstelle auf einem HDFernseher wiedergegeben werden.
Ein Aufnahmemodus für die vollständig manuelle Steuerung bringt ambitionierten Fotografen kreative Freiheit pur.
 
Die Leistungsstärke des neuen DIGIC-4-Bildprozessors führt zu einer optimierten Motion- und Face-Detection-Technologie.
Motion Detection unterscheidet Kameraverwacklungen von bewussten Bewegungen des Motivs und stimmt in Kombination mit dem Servo AF darauf die Einstellungen der Kamera zur Minimierung von Verwacklungsunschärfen ab.
Face Detection erkennt Gesichter im Motiv, auf die die Kamera dann kontinuierlich scharf stellt.
Starke Pluspunkte bei der Canon Face Detection sind der FaceSelf-Timer für Gruppenfotos, in denen der Fotograf bequem mit auf das Bild kommt, und die Rote-Augen-Korrektur.
 
Als weitere Technologie-Komponente spielt die innovative Canon-i-Contrast- Technologie ihre Stärken bei Bildern mit dunklen Bildbereichen aus:
Sie erhöht den Kontrast ausschließlich in diesen Bildpartien, anstatt lediglich die Gesamthelligkeit zu steigern, was zu überbelichteten Bildern führen würde. Der Canon-DIGIC-4- Prozessor ist zudem die Basis für schnelle Reaktionszeiten, effizientes Pufferspeicher-Handling und minimiertes Bildrauschen.
 
Manche Motive muss man einfach in bewegten Bildern festhalten:
Dafür hat die PowerShot SX200 IS einen Movie-Modus, in dem Movieclips sogar in High- Definition-Auflösung (720p) aufgezeichnet werden.
Ideal für die Wiedergabe der Clips auf einen High-Definition-Fernseher ist die integrierte HDMI™-Schnittstelle für den Anschluss der Kamera.
Das 3,0 Zoll große LC-Display der Kamera macht nicht nur Bildkomposition und Bildprüfung angenehm einfach, der große Betrachtungswinkel ist auch ideal für das direkte Betrachten von Bildern und Movieclips.
Die neue Benutzeroberfläche verfügt zudem über eine intelligente Funktion zur Einblendung praktischer Tipps und Tricks für die unterschiedlichen Einstellungen und ihre Auswirkungen auf die Aufnahmen.
 
Lieferumfang:
PowerShot SX200 IS, Trageriemen, Akku, Akku-Ladegerät, USB-Kabel, Video-Kabel
";2;False;0;;;Canon PowerShot SX200 IS;canon-powershot-sx200-is;True;True;P-1720;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;259.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40039,860474537;"56;2095";25;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000351-canon-powershot-sx200-is.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000352-canon-powershot-sx200-is.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000353-canon-powershot-sx200-is.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Philips DLA 1619 H/10 Neopren-Tasche für iPod Shuffle ";"Philips DLA 1619 H/10 Neopren-Tasche für iPod Shuffle schwarz ";"

Philips DLA 1619 H/10 Neopren-Tasche für iPod Shuffle schwarz

Armband, Sichtfenster und Gürtel-Clip
 
Ob für Sport oder Erholung, Ihr iPod ist immer dabei. Dafür ist das Action Jacket die allumfassende Lösung.
Verwenden Sie das verstellbare Armband beim Sport und bewahren Sie den iPod shuffle nach dem Sport in der schützenden Hülle auf.
 
  • Aktiver Schutz
  • Durchsichtiges Fenster zum Schutz des Bildschirms
  • Neopren schützt vor Schweiß
  • Vielseitige Positionierung
  • Anpassbares Sportarmband
  • Das anpassbare Sportarmband ist dehnbar und passt sich so unterschiedlichsten Größen an. Es ist mit einem
  • Klettverschluss versehen, sodass Ihr Gerät bei jeder Aktivität sicher verstaut ist.
  • Sichtfenster für das Display
  • Beim Sport schützt dieses durchsichtige Fenster den Bildschirm des Geräts und ermöglicht gleichzeitig die
  • Bedienung des Geräts.
  • Feuchtigkeitsbeständiges Neopren
  • Diese Neoprentasche bietet eine gepolsterte, feuchtigkeitsbeständige Schicht für Ihr Gerät und schützt es beim
  • Sport vor Schweiß und den Elementen.
";2;False;0;;;"Philips DLA 1619 H/10 Neopren-Tasche für iPod Shuffle ";philips-dla-1619-h10-neopren-tasche-fuer-ipod-shuffle;True;True;P-1520;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;24.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40035,8124652778;51;6;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000350-philips-dla-1619-h10-neopren-tasche-fur-ipod-shuffle.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Hama MP3-Tasche iPod nano 5G;Hama MP3-Tasche iPod nano 5G Transparent;"
Hama MP3-Tasche iPod nano 5G Transparent 

 
robuste, passgenaue Silikontasche; perfekte Passform, sitzt wie eine zweite Haut;
Ausstattung: Aussparungen für Bedienelemente und Anschlüsse;
3D-Sticker für bessere clickwheel Steuerung; abnehmbares Trageband
Displayschutzfolie; Serie: Sport Case; Farbe: Transparent; Material: Silikon;
Medium: MP3-Player; Typ: Fenstertasche; für MP3-Marke: für iPod Nano 5G
";2;False;0;;;;hama-mp3-tasche-ipod-nano-5g;True;True;P-1510;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;14.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40035,80875;"51;2095";18;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000349-hama-mp3-tasche-ipod-nano-5g.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Panasonic DMR EH 695 EG DVD- und Festplatten-Rekorder 320 GB;"Panasonic DMR EH 695 EG DVD- und Festplatten-Rekorder 320 GB ";"
Panasonic DMR EH 695 EG DVD- HDD-Rekorder 320 GB

 
HDMI, SDHC-Kartenslot, USB 2.0

Der neue DIGA DVD-Recorder DMR-EH695 mit analogen Kabeltuner steht für hervorragende Aufnahme- und Wiedergabequalität, Musikgenuss sowie ein Maximum an Kompatibilität.
 
Auf die 320 GB Festplatte können bis zu 567 Stunden (EP Modus) oder aufgrund eines sehr guten Encoders bis zu 284 Stunden Aufnahmekapazität in DVD Qualität (LP-Modus) gespeichert werden.
 
Die Super Multi Format Aufnahmefähigkeit des DMR-EH695 verarbeitet alle DVD Formate [DVD-RAM, -RW, -R, -R (DL), +RW, +R, +R (DL)] und spielt neben diesen Formaten zusätzlich JPEG, MP3, WMA und DivX Daten ab. Auf die integrierte ""Jukebox"" lassen sich schnell und einfach Ihre Musik CDs in 12-facher Kopiergeschwindigkeit (6min.)
in unkomprimiertem LPCM auf die Festplatte kopieren.
 
Die Album, Interpreten und Titelinformationen sind bereits auf der vorinstallierten Gracenote-Datenbank auf der Festplatte hinterlegt, sodass eine lästige Eingabe entfällt.
 
Über den USB Eingang können Sie Ihre MP3/WMA-Musikinhalte, JPEG Bilder oder MPEG2 Filme vom Camcorder ebenfalls auf die Festplatte kopieren oder abspielen. Neben diesen Formaten können auch DivX-Dateien abgespielt werden. Ebenfalls in Front bietet ein SDHC Slot die Möglichkeit, HD-JPEG oder MPEG2 Aufnahmen auf die Festplatte zu kopieren oder abzuspielen.
 
Der DMR-EH695 skaliert jedes Bildmaterial über die HDMI-Schnittstelle in eine maximale HDTV Auflösung mit 1080 Zeilen (Full HD).
 
Die neue praktische VIERA LINK Funktion, ausschließlich über HDMI mit den VIERA Flachbildschirmen nutzbar, bietet Ihnen komfortable Bedienung aller Panasonic Geräte mit nur einer Fernbedienung! Einfach, schnell und problemlos.
 
HDMI-Ausgang (HDMI Ver. 1.3)
USB-Anschluss (USB 2.0 High Speed)
SD-HC Karten-Slot
DV Eingang (IEEE1394/iLink)
Komponentenausgang (YUV)
2x Scart-Anschluss
Front-AV (S-Video/Video/Audio-IN)
S-Video Ausgang (Hosiden)
Video-Ausgang (Cinch)
Audio Ausgang (Cinch)
Optischer Digitalausgang (PCM, Dolby Digital, DTS, MPEG)
 
Lieferumfang:
Panasonic DMR-EH695EGK, Fernbedienung
";2;False;0;;;"Panasonic DMR EH 695 EG DVD- und Festplatten-Rekorder ";panasonic-dmr-eh-695-eg-dvd-und-festplatten-rekorder-320-gb;True;True;P-1790;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;419.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40035,2792476852;64;12;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000348-panasonic-dmr-eh-695-eg-dvd-und-festplatten-rekorder-320-gb.jpg;;;3;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Qualitätsakku für Canon EOS 450D, 500D und 1000D ";"Qualitätsakku für Canon EOS 450D, 500D und 1000D Typ: Lithium-Ion-Akku ";"

Qualitätsakku für Canon EOS 450D, 500D und 1000D

Typ: Lithium-Ion-Akku
 
Leistungsstark - hohe Qualität und doch günstig
Dieser Qualitätsakku zeichnet sich durch seine Langlebigkeit und Zuverlässigkeit aus und steht dem Original von Canon LP-E5 in nichts nach.
Dieser Akku passt auch in den Batteriegriff Canon BG-E5. Der Akku ist mit einem Chip ausgestattet, welcher Überladung und Überhitzung verhindert.
 
Technische Details
• Typ: Lithium-Ion-Akku
• Spannung: 7,4v
• Kapazität: 1080mAh
• Gewicht: 50g
• Überladungs-/Überspannungsschutz
";2;False;0;;;Qualitätsakku für Canon EOS 1000D;qualitaetsakku-fuer-canon-eos-450d-500d-und-1000d;True;True;P-1710;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;29.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40035,2271412037;56;25;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000347-qualitatsakku-fur-canon-eos-450d-500d-und-1000d.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Logitech V150 Laser Mouse ";"Logitech V150 optische Notebook Maus schnurgebunden silber ";"Logitech V150 optische Notebook Maus schnurgebunden silber
 
 
 
Plug & Play: Die Maus muss nur an einem USB-Anschluss angeschlossen werden und ist sofort einsatzbereit.
Laserabtastung: Erleben Sie Laser für präzise, flüssige Abtastung auf fast jeder Oberfläche
Tilt Wheel Plus Zoom¿: Horizontale Bildläufe. Vergrößern und verkleinern Sie mühelos Fotos und Tabellen.
Handgerechte Form: Komfort für Rechts- und Linkshänder.
Besonders kompaktes Design: Praktisch für unterwegs. ";2;False;0;;;"Logitech V150 Laser Mouse for Notebooks ";logitech-v150-laser-mouse;True;True;P-2790;;;False;0;False;;False;False;0;False;0;1;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;29.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40028,639212963;21;11;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000346-logitech-v150-laser-mouse.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Panasonic DMP-BD60EG-K Blu-ray Player;"Panasonic DMP-BD60EG-K Blu-ray Player schwarz ";"

Panasonic DMP-BD60EG-K Blu-ray Player schwarz

 
HDMI, Upscaling 1080p, USB 2.0

 
 Glänzt als wahre Allround-Unterhaltunskünstler
Moderne Schnittstellen wie SD/SDHC-Slot und USB-Eingang mit Multimediamöglichkeiten
Über den Ethernet-Port Zugriff auf den I/P-Service VIERA Cast
Z.B. YouTube-Videos und Fotos über den Online-Bilderdienst Picasa ansehen
Zahlreiche Komfortmerkmalen wie BD-Live und Bonus View
Wiedergabe-Formate: Blu-ray Video, Blu-ray Disc (BD-R), Blu-ray Disc wiederbeschreibbar (BD-RE), DVD-Video, DVD+R, DVD-R, DVD+RW, DVD-RW, DVD+R DL, DVD-R DL, DVD-RAM,
CD-Audio, CD-R, CD-RW, MP3, DivX, Foto-Formate JPEG
Audio: Dolby Digital Plus, Dolby TrueHD, DTS-HD, MPEG2
Anschlüsse: Audio-Ausgang, Video-Ausgang, Video-Farbkomponenten-Ausgang (YPbPr / YUV), Digital-Ausgang Optisch, Speicherkarten-Steckplatz, HDMI, USB, Netzwerk
Farbe: schwarz
";2;False;0;;;Panasonic DMP-BD60EG-K Blu-ray Player;panasonic-dmp-bd60eg-k-blu-ray-player;True;True;P-1900;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;164.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40025,7325578704;"61;2095";12;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000343-panasonic-dmp-bd60eg-k-blu-ray-player.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"LG W2261VP 54,6 cm (21,5 Zoll) Widescreen TFT Monitor HDMI/ DVI-D/ VGA ";"LG W2261VP 54,6 cm (21,5 Zoll) Widescreen TFT Monitor HDMI/ DVI-D/ VGA (Kontrastverhältnis 50000:1, Reaktionszeit 2ms) schwarz ";"
LG Electronics präsentiert: TFT Monitor FLATRON W2261VP
Multimedia Monitor mit erstklassigen Werten
Dank HDMI bietet dieser 22 Zoll LG Monitor vielfältige und zukunftssichere Anschlussmöglichkeiten. Mit seinem natürlichen 16:9 Blickfeld-Format eignet er sich perfekt für Gamer und Multimedia-Fans – nicht zuletzt auch aufgrund der schnellen Reaktionszeit von 2ms und dem hohen Kontrast von 50.000:1. Genießen Sie mit den innovativen Fun-Funktionen absoluten Bedienkomfort, dank Full HD und f-Engine perfekte Bildqualität und ein wertiges, edles Design in einem!
 
Beschreibung der Features
 
Perfektion in Full HD
Höchste Präzision und beste Qualität in der Darstellung sind in allen Bereichen – ob für Filme, Computerspiele, Multimedia- und Of?ce-Anwendungen – garantiert. Pixel für Pixel stellt dieser LG Monitor in einer Auflösung von 1920x1080 die Bilder unskaliert genauso dar, wie sie die Quelle liefert. Das sorgt für eine reibungslose Wiedergabe und garantiert extrem scharfe und kristallklare Bilder, die selbst bei Action-Szenen oder Sportübertragungen nicht ins Ruckeln geraten.
 
Hochgenuss im 16:9 Breitbildformat
Der W2261VP LG Monitor mit integriertem 16:9 Panel bringt überragende Bildqualität mit Full HD-Au?ösung im Breitbildformat zu Ihnen nach Hause. Das 16:9 Panel ist ein natürliches Blickfeld-Format, das Ihre Augen nicht übermäßig beansprucht. So können Sie Ihren Monitor sowohl für actiongeladene BluRay- oder DVD-Filme, zum digitalen Fernsehen oder für professionelle Aufgaben am PC ideal nutzen. Super bequem beim Arbeiten: Es lassen sich problemlos zwei DIN-A4-Hochformate nebeneinander anzeigen.
 
Scharfer Kontrast
Der ultra hohe Kontrast von 50.000:1 mit DFC (Digital Fine Contrast) bringt tiefstes Schwarz und strahlend helles Weiß auf Ihren Bildschirm. Farben zeigen sich brillant und lebensecht, so dass das Filmerlebnis am PC eine neue Dimension erreicht.
 
Schnelle Reaktionszeit
Durch die enorm schnelle Reaktionszeit der Hintergrundbeleuchtung von nur 2 Millisekunden werden Bewegungsunschärfen eliminiert und ein ruckelfreies Bilderlebnis garantiert. Bei Action?lmen, Sportübertragen oder Videogames verpassen Sie nun nichts mehr! Und dank des angenehm großen Blickwinkels von 170° kommen auch die richtig anspruchsvollen Multimedia- und Office-Anwender voll auf ihre Kosten.
 
Connected: HDMI
HDMI steht für ""High Definition Multimedia Interface"". Hierbei handelt es sich um eine zukunftssichere Schnittstelle für die volldigitale Übertragung von Audio- und Video-Daten in der Unterhaltungselektronik. Dieser Anschluss verbindet portable HDMI-Abspielgeräte mit Ihrem Display und ermöglicht eine verlustfreie High-Definition Bild- und Tonübertragung wobei eine Bildtiefe von bis zu 48-bit erreicht werden kann. Beim W2261VP Monitor haben Sie diesen komfortabel nutzbaren HDMI- sowie einen DVI-D Eingang mit HDCP Kopierschutzunterstützung.
 
Innovative FUN-Funktionen
Nutzen Sie praktische Photoeffekte für Farbkorrekturen in Bildern und Filmen oder die ez-Zooming-Funktion zur hochauflösenden Ausschnittvergrößerung von Bild und Text. Die 4:3 Formatumschaltung sorgt zudem für verzerrungsfreien Film- und Spielgenuss.
 
Alle Daten im Überblick
 
22"" TFT Monitor für den anspruchsvollen Multimedia Anwender im 16:9 Breitbildformat.
Funktionelles edles Design in hochglänzendem Schwarz
Ultra schnelles Panel mit kurzer Reaktionszeit von nur 2 ms (ISO) und sehr großem Blickwinkel von 170°; ideal für Multimedia-Anwender oder Gamer.
Ultra hoher Kontrast von 50.000:1 mit DFC (Digital Fine Contrast)
Full HD Auflösung (1920 x 1080 Pixel). Formatfüllende Darstellung von zwei DIN-A4 Seiten gleichzeitig.
f-Engine – LG's welterster Bildverbesserer Chip garantiert kristallklare und brillante Bilder ohne Farbverfälschung in Echtzeit für Film, Foto oder Anwender.
Neue ergonomische Menüführung mit Visual OSD
Fun Taste für Photoeffekte zur kreativen Darstellung von Bildern wie z.B. Sepia, kalt, und Gaussche Unschärfe. ez Zooming zur Änderung der Auflösung, oder ARC Formatumschaltung von 4:3 auf 16:9 zur formatgetreuen Darstellung von älteren Programmen.
HD fähig und zukunftssicher HDMI Eingang (bis 1080p) und DVI-D Eingang mit HDCP Kopierschutzunterstützung. Zusätzlicher VGA 15 Pin D-Sub Eingang zum Betrieb an zwei Rechnern.
Integriertes Netzteil
Kopfhörerausgang
Externes Netzteil 
";2;False;0;;;"LG W2261VP 54,6 cm (21,5 Zoll) Widescreen TFT Monitor HDMI/ DVI-D/ VGA ";lg-w2261vp-546-cm-215-zoll-widescreen-tft-monitor-hdmi-dvi-d-vga;True;True;P-2520;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;239.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40025,6372800926;"11;2095";19;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000337-lg-w2261vp-546-cm-215-zoll-widescreen-tft-monitor-hdmi-dvi-d-vga.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000338-lg-w2261vp-546-cm-215-zoll-widescreen-tft-monitor-hdmi-dvi-d-vga.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000339-lg-w2261vp-546-cm-215-zoll-widescreen-tft-monitor-hdmi-dvi-d-vga.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Western Digital My Passport Essential 500 GB ";"Western Digital BAAA5000ABK My Passport Essential 500GB ";"
Western Digital BAAA5000ABK My Passport Essential 500GB 
 
Unsere kleinste tragbare Festplatte aller Zeiten
Ihre gesamten Daten auf einen Blick und mühelose Widerhergestellung Ihrer Daten
Passwortschutz und 256-bit Hardware basierte Verschlüsselung
Plug-and-play-bereit für Windows-PCs
Lieferumfang: Western Digital My Passport Essential 500GB externe Festplatte,
SmartWare-Software, USB-Kabel, Schnellinstallationsanleitung
";2;False;0;;;Western Digital My Passport Ess. 500GB schwarz;western-digital-my-passport-essential-500-gb;True;True;P-2570;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;109.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40015,1174768519;14;21;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000336-western-digital-my-passport-essential-500-gb.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;LG BD 370 Blu-ray Disc Player schwarz;"LG BD 370 Blu-ray Disc Player schwarz ";"

LG BD 370 Blu-ray Disc Player schwarz 

HDMI, Upscaler 1080p, BD live, You Tube-Video Client, Ethernet, USB 2.0

Der neue BD-370 verbindet wie kein anderer Blu-ray Player das Internet mit dem Fernsehen.
Über eine LAN-Verbindung können Sie YouTube Video-Streams wiedergeben.
Die BD-Live Funktion versorgt Sie über das Internet mit Zusatzinformationen zu den Filmen,
wie z.B. Kommentare oder Extra-Material. Wie von LG gewohnt, liefert der BD-370 perfekte Bildqualität
und ist, kombiniert mit einem FullHD TV, unschlagbar in Sachen Bildqualität.
 
Blu-ray Disc Player zur Wiedergabe von: Blu-ray Discs, BD-R(E), Video DVDs (PAL & NTSC), DVD+R(W), DVD-Dual Layer,
DVD+R Double Layer, Audio-CD, DTS-CD, MP3 CD, WMA CD, PNG, CD, DivX CD, JPEG CD, CD-R(W)
Unterstützung interaktiver Blu-ray Disc Standard-Inhalte & BD Live 2.0
YouTube™ Video-Streaming Wiedergabe über LAN
USB 2.0 und HDMI 1.3 1080p Ausgang mit SIMPLINK & Deep Colour,
A/V-Ausgang (Cinch), Komponentenausgang YUV, RJ45 LAN-Anschluß
Dolby TrueHD, Dolby Digital, Dolby Digital Plus, DTS-HD, DTS, LPCM, MP3, WMA, MPEG1/2 L2
";2;False;0;;;LG BD 370 Blu-ray Disc Player schwarz;lg-bd-370-blu-ray-disc-player-schwarz;True;True;P-1890;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;147.9000;147.9000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40013,6568865741;61;19;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000333-lg-bd-370-blu-ray-disc-player-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000334-lg-bd-370-blu-ray-disc-player-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000335-lg-bd-370-blu-ray-disc-player-schwarz.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Samsung DVD-HR 775 A DVD-/Festplatten-Rekorder ";"Samsung DVD-HR 775 A DVD-/Festplatten-Rekorder 250 GB ";"
Multiformat DVD-Recorder im 55 Millimeter Slim Design mit 250 GB HDD,
 
USB 2.0, MPEG4 (DivX), HDMI™-Ausgang (1.080p/ 1.080i / 720p),
 
Anynet+ (HDMI-CEC), TimeShift, TimeSlip und ShowView.
 
 
Aufnahme auf Festplatte
Die eingebaute Festplatte mit 320 / 250 / 160 GB im DVD-HDD-Recorder macht‘s möglich: Im EP-Modus können Sie bis zu 534 / 421 / 264 Stunden Filme aufzeichnen.
 
One-Touch-Aufnahme
Die Samsung DVD-Recorder machen das Aufzeichnen leichter denn je. Ein Knopfdruck genügt – schon sucht der Samsung Recorder nach dem verfügbaren Aufnahmeplatz auf der Disc und beginnt mit der Aufnahme. Einmal drücken bedeutet Aufnahme bis zu 30 Minuten, zweimal drücken bis zu einer Stunde. Mit jedem Tastendruck zeichnet der Samsung DVD-Recorder weitere 30 Minuten des ausgewählten Programms auf. Die Aufnahmezeit auf einer Disc beträgt je nach Aufnahmemodus maximal 240 Minuten.
 
Automatische Fehlerkorrektur
Die Bildqualität der auf DVD gespeicherten Daten kann bei einer verbogenen Disc verzerren. Der Grund: Diese Disc lässt sich aufgrund der Unregelmäßigkeit der Laserreflexion nicht korrekt lesen. Zur Verbesserung der Lesbarkeit sind Samsung Recorder mit einer automatischen Fehlerkorrektur-Technologie ausgestattet. Diese Technik verbessert die Datenleserlichkeit selbst bei Discs, die Unregelmäßigkeiten aufweisen.  VBR-Technologie
Mit der VBR (Variable Bit Rate)-Technologie kann die Aufnahmezeit durch Einstellen des Aufnahmemodus auf bis zu 16 Stunden verlängert werden. Um Bilder auf DVD-RW und DVD-R aufzuzeichnen, steuert die VBR-Kodiertechnik die Komprimierungsrate von MPEG2 in Echtzeit und maximiert dadurch den verfügbaren Speicherplatz auf der Disc.
 
Was bedeutet White Strategy?
Bei der ""Präzise Aufzeichnung und Wiedergabe""-Technologie passen sich die gespeicherten Daten sauber in den optimalen Bereich an. Die Daten, die ohne diese Technik gespeichert werden, viel mehr Platz ein, was zu einer Datenüberlappung führen kann. Dank der ""Präzisen Aufzeichnung und Wiedergabe"" werden die Daten im Samsung DVD-Recorder noch präziser gespeichert. So entstehen kristallklare Bilder.
 
Was ist HDMI™?
HDMI™ (kurz für High-Definition Multimedia Interface) ist eine volldigitale Audio/Video-Schnittstelle, die Bild- und Tondaten mit einem einzigen Digitalkabel zwischen Digital- und Audiogeräten überträgt. Es unterstützt die Videoformate Standard, Enhanced oder High-Definition sowie die Audioformate Standard bis mehrkanaligen Surround-Sound. Die Vorteile: unkomprimierte digitale Videodaten (mit Bandbreiten bis zu 5 Gigabyte pro Sekunde), ein Anschluss statt vieler Kabel und Datenaustausch zwischen Bildquelle und DTV. 
";2;False;0;;;;samsung-dvd-hr-775-a-dvd-festplatten-rekorder;True;True;P-1940;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;269.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40013,6237847222;63;5;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000331-samsung-dvd-hr-775-a-dvd-festplatten-rekorder.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000332-samsung-dvd-hr-775-a-dvd-festplatten-rekorder.jpg;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Canon Digital IXUS 95 IS Digitalkamera Silver;"Canon Digital IXUS 95 IS Digitalkamera Silver ";"
Canon Digital IXUS 95 IS Digitalkamera Silver

10 Megapixel, 3-fach opt. Zoom, 2,5"" Display, Bildstabilisator
 
Die Digital IXUS 95 IS vereint exquisiten Schick mit exzellenter Leistung und hohem Komfort.
Der innovative Smart-Auto-Modus nutzt auf intelligente Art die Scene-Detection-Technologie.
Das Ergebnis: optimierte Einstellungen für tolle Bilder. Kompaktes und schickes IXUS-Design mit 10 Megapixeln in 3,0fach optisches Zoom

mit optischem Bildstabilisator Scene-Detection-Technologie Brillante Aufnahmen Face-Detection-Technologie DIGIC 4 2,5-Zoll-PureColor-LCD II i-Contrast 17 Aufnahmemodi VGA-Movieclips
Technische Daten der Canon Ixus 95 IS : Auflösung (MP) 10 Sensor-Größe 1/2.3 LCD-Größe (cm) 6.35 Speicher SD / SDHC interner Speicher (MB)

optischer Zoom (x-fach) 3 numerischer Zoom (x-fach) 4 Bildstabilisator Ja Optischer Zoom Nein Brennweite 35 - 105 Lichtstärke 2.8 - 4.9 Video-Modus JA

Max. Video-Auflösung(Pixel) 640 x 480 Abmessungen (B x H x T mm) 88,5 x 54,8 x 21,8 Gewicht (g) 120 Akku NB-6L
 
Lieferumfang:
Digital IXUS 95 IS, Trageriemen, Akku, Akku-Ladegerät, USB-Kabel, Video-Kabel
";2;False;0;;;"Canon Digital IXUS 95 IS Digitalkamera ";canon-digital-ixus-95-is-digitalkamera-silver;True;True;P-1700;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;189.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40008,648287037;56;25;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000324-canon-digital-ixus-95-is-digitalkamera-silver.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000325-canon-digital-ixus-95-is-digitalkamera-silver.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000326-canon-digital-ixus-95-is-digitalkamera-silver.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Garmin TOPO DVD Deutschland Digital 25 ";"Garmin TOPO DVD Deutschland Digital 25 ";"
Garmin TOPO DVD Deutschland Digital 25 

 
Topographische Rasterkarte von Deutschland im Maßstab von 1:25.000
 
 
Topographische Rasterkarte
Maßstab 1:25.000
3D-Geländedarstellung mit Flugmodus
Erstellen von Höhenprofilen
Übertragen von Routen, Tracks und Wegpunkten
";2;False;0;;;;garmin-topo-dvd-deutschland-digital-25;True;True;P-2050;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;159.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40007,1684027778;67;44;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000323-garmin-topo-dvd-deutschland-digital-25.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Garmin Topo DVD Deutschland V3;"Garmin Topo DVD Deutschland V3 Gesamt Digitale topographische Karte gesamt Deutschland auf DVD und MircoSD-Karte ";"

Garmin Topo DVD Deutschland V3 Gesamt

 
Digitale topographische Karte gesamt Deutschland auf DVD und MircoSD-Karte
 
.
Die neue topographische Karte gesamt Deutschland
enthält zusätzlich zu detaillierten Straßen- und Wegedaten mehr als 8.000 km überregionale Wanderrouten und über 60.000 km Radrouten.
Innerhalb dieses Routennetzes kann sich der Nutzer von einem bestimmten Ausgangspunkt zu einem Zielpunkt routen lassen.
Beispiele für Routen: Rothaarsteig, Rennsteig, Altmühltal-Panoramaweg, Harzer Hexensteig, 66 Seen Wanderweg, Premiumwanderwege Saarland und viele mehr.
Neu ist auch, dass die Kartensoftware erstmals kompatibel mit Apple MacIntosh Computern ist (ab OS X 10.4 aufwärts).
Ob zu Fuß oder auf dem Mountain-Bike,
wer viel draußen unterwegs ist, setzte früher Papierkarten ein. Seit mehreren Jahren gibt es von Navigationsspezialist Garmin GPS-Geräte
die topografische Karten darstellen können (Karten im MapSource-Format). Ein Routing, wie man es von Navis aus dem Auto kennt, war mit diesen Karten bislang aber nicht möglich.
Die neueste Version der “Topo Deutschland v3” macht nun erstmals das Routing auf 8.000 km Wanderrouten und rund 60.000 km Radrouten möglich!
Einfach Start- und Zielpunkt eingeben, das Gerät schlägt die Route vor, und los geht’s. Visuelle Abbiegehinweise führen dann bequem und sicher zum Ziel.
Dies sollte auch den größten GPS-Skeptiker positiv stimmen.
Ebenfalls praktisch:
Die neue Topo Deutschland V3 wird mit einer bereits programmierten SD-/microSD Datenkarte ausgeliefert.
Das erspart ein Freischalten der Karte auf dem PC und das Übertragen der Karte auf das Gerät.
Die Datenkarte wird einfach in den Slot des GPS-Gerätes geschoben und schon kann es losgehen.
Eine Verwendung der Daten von der DVD auf dem Computer ist natürlich nach wie vor möglich.

";2;False;0;;;Garmin Topo DVD Deutschland V3;garmin-topo-dvd-deutschland-v3;True;True;P-2040;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;209.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40007,1559606481;67;44;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000322-garmin-topo-dvd-deutschland-v3.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"NAVIGON 2310 Navigationssystem Europa ";"NAVIGON 2310 Navigationssystem Europa ";"

NAVIGON 2310 Navigationssystem Europa

 
40 Länder, inklusive TMC, NAVIGON MyRoutes, Clever Parking , TMC-Routenplanung
 
 
NAVIGON 2310 Kann noch mehr,als das Äußere verspricht.
Was macht eigentlich ein Schmuckstück aus? Erstmal muss es natürlich gut aussehen.
Im ersten Moment könnte man die 23er-Serie von NAVIGON für so ein typisches, kleines Accessoire halten.
Aber nicht nur das schicke Design begeistert. Denn auch was die Features angeht, kann die 23er-Serie locker mithalten:
Mit TMC- Routeninfo stehen Sie nie wieder im Stau, NAVIGON MyRoutes findet jederzeit die für Sie beste Strecke und mit dem POI-Klick erhalten Sie alle Infos zu Ihrem gewählten Sonderziel.
Und wenn Sie das immer noch nicht überzeugt, dann sehen Sie sich mal den Preis an.
 
NAVIGON MyRoutes
Je nachdem, welcher Fahrertyp Sie sind, empfiehlt Ihnen NAVIGON MyRoutes die beste Route – zugeschnitten auf Ihren persönlichen Fahrstil, den Wochentag und die Tageszeit.
Darüber hinaus zeigt Ihnen Ihr NAVIGON bis zu zwei weitere Routen. Das schafft Transparenz. Sie entscheiden, ob Sie unserer Empfehlung folgen oder eine der Alternativen wählen.
 
TMC-Routeninfo
zeigt ihnen im Fall einer Staumeldung eine Alternativroute mit aktualisierter Entfernung und Ankunftszeit. Sie entscheiden, ob eine Umfahrung in Ihrem Fall sinnvoll ist oder ob Sie die ursprüngliche Route beibehalten wollen.
 
Reality View Pro
zeigt Straßen nicht als Linien, sondern realistisch aus Asphalt und mit Mittelstreifen. So behalten Sie an Autobahnkreuzen und Ausfahrten leichter den Überblick.
 
Fahrspurassistent Pro
hilft Ihnen selbst durch den hektischsten Straßenverkehr hindurch. Vorausschauend und übersichtlich zeigt er Ihnen an, auf welche Fahrspur Sie für Ihren nächsten und übernächsten Abbiegepunkt wechseln müssen.
 
Clever Parking
hilft Ihnen bei der Parkplatzsuche. Kurz vor Ihrem Ziel zeigt Ihnen Clever Parking Parkplätze in der näheren Umgebung an.
In Deutschland werden Sie sogar über Parkgebühren informiert. So vermeiden Sie langes Suchen und sparen dabei Geld.
 
Lieferumfang:
PNA  2310 (3,5"" im 4:3 Format) | Kurzanleitung | Kfz-Ladekabel mit integrierter TMC-Antenne | Halterung | Vorinstalliertes Kartenmaterial für 40 Länder | USB-Kabel
";2;False;0;;;;navigon-2310-navigationssystem-europa;True;True;P-2150;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;159.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39998,914525463;68;14;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000321-navigon-2310-navigationssystem-europa.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Panasonic Lumix DMC-FS6 Digitalkamera schwarz;"Panasonic Lumix DMC-FS6 Digitalkamera schwarz ";"

Panasonic Lumix DMC-FS6 Digitalkamera schwarz

 
8 Megapixel, 4-fach opt. Zoom, 2,5"" Display, Bildstabilisator
 
 
Im Intelligenten Automatik (iA)-Modus werden die 5 wichtigsten Motivprogramme automatisch optimal auf die jeweilige Szene eingestellt.
Neben der Motiverkennung kombiniert iA weitere wichtige Funktionen, wie den optischen Bildstabilisator OIS, die Bewegungserkennung (Intelligente ISO-Steuerung),
eine optimierte Gesichtserkennung mit digitaler Rotaugen-Korrektur.
So sind scharfe, natürliche und schöne Fotos selbst für (Neu-)Einsteiger möglich.
Der reaktionsschnelle Venus Engine IV-Bildprozessor gehört schon bei diesem Einsteigermodell zur Grundausstattung.

Lichtstarkes F2,8 Leica DC Vario-Elmarit Objektiv
Hochauflösendes 6,4 cm LC-Display [230.000 Pixel]
4x optischer Zoom [KB: 33-132 mm]
Intelligente Automatik [u.a. Gesichtserkennung]
 
Lieferumfang:
Digitalkamera, Lithium Ionen Akku, Ladegerät, USB-Kabel, Trageriemen, Audio / Video-Kabel, CD-ROM, Sotware
";2;False;0;;;"Panasonic Lumix DMC-FS6 ";panasonic-lumix-dmc-fs6-digitalkamera-schwarz;True;True;P-1770;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;189.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39998,8940393519;58;12;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000317-panasonic-lumix-dmc-fs6-digitalkamera-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000318-panasonic-lumix-dmc-fs6-digitalkamera-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000319-panasonic-lumix-dmc-fs6-digitalkamera-schwarz.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Western Digital WD TV HD Media Player;Western Digital WD TV HD Media Player;"
Western Digital WD TV HD Media Player
 
 
In Kombination mit einem tragbaren My Passport-Laufwerk ist dieser Player die bequemste Methode, Filme oder selbstgedrehte Videos wiederzugeben,
digitale Musik in hoher Qualität abzuspielen und Diashows Ihrer Familienfotos in hoher Auslösung von der Festplatte in Ihrem Fernseher anzuzeigen.
Auch mit gängigen USB-Laufwerken und Digitalkameras, Camcordern und tragbaren Media-Playern, die als Massenspeichereinheiten erkannt werden, kompatibel.
Ideal geeignet für eine störungsfreie Wiedergabe von Filmen, Heimvideos, digitaler Musik und Fotos von der Festplatte auf Ihrem Fernsehgerät.
 
HDMI- und FBAS-Anschlüsse - Der HDMI-Anschluss (HDMI – High-Definition Multimedia Interface) ermöglicht den Anschluss an HDTV-Geräte der höchsten Qualität oder an ein Heimtheater.
Zusätzliche kombinierte (RCA-)Ausgänge gewährleisten die Kompatibilität mit praktisch allen Fernsehgeräten.
 
Highlights
maximale Transferrate: 480 Mb/s über USB 2.0
USB 2.0 Anschluss
für PC oder Macintosh Computer
Lieferumfang: HD Media Player, kompakte Fernbedienung einschließlich Batterien,
Software für Medienkonvertierung (nur für Windows), kombiniertes Audio/Video-Kabel, Netzteil, Schnellinstallationsanleitung
";2;False;0;;;Western Digital WD TV;western-digital-wd-tv-hd-media-player;True;True;P-2560;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;119.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39997,7782638889;14;21;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000316-western-digital-wd-tv-hd-media-player.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"TomTom 220V Netzteil ";"TomTom 220V Netzteil ";
220V Netzteil TomTom Navigation

Ladegerät mit abgewinkeltem 90° Spezialstecker

Steckerlader für Tom Tom Serien: ONE XL Europe HD Traffic Regional,
Go Serien 520 Go 720 Go 740 Go 920 Live XL XL LIVE IQ Routes
Netzteil Ladegerät 240 Volt Output: 5.5V +/- 5%
Mit Ladekontrollleuchte (LED), nur 85 Gramm
Hochflexibeles, kerbfestes Kabel, beste Qualität
Auslieferung in Kartonbox und Schutzumschlag
CE, beste Qualität original von Spartechnik
;2;False;0;;;"Reiseladegeraet / Netzteil / Ladegeraet fuer TomTom ";tomtom-220v-netzteil;True;True;P-1970;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;14.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39986,6084953704;66;4;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000311-tomtom-220v-netzteil.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Tom Tom One Hard Case XL schwarz ";"Tom Tom One Hard Case XL schwarz ";"

Tom Tom One Hard Case XL schwarz
 
 

Hard Case Tom Tom One XL, Schwarz
passgenaue, stoßfeste Tasche aus Nylon/EVA
Farbe: Schwarz
Ausstattung:
mit zusätzlichem Staufach für Zubehör
Handschlaufe für einfachen Tragekomfort
";2;False;0;;;"Tom Tom One Hard Case XL schwarz ";tom-tom-one-hard-case-xl-schwarz;True;True;P-1960;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;20.9900;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39986,6020023148;66;4;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000265-tom-tom-one-hard-case-xl-schwarz.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"TomTom XL IQ RoutesTM-Edition Europe ";"TomTom XL IQ RoutesTM-Edition Europe mit TMC ";"

TomTom XL IQ RoutesTM-Edition Europe mit TMC
 

42 Länderkarten, Fahrspurassistent, Text-to-Speech, Intelligente Routenberechnung,TMC
 

TomTom Navigationsgerät XL IQ Routes Edition Europe 42 Traffic mit 4,3 Zoll Farb-Touchscreen, RDS/TMC,
42 vorinstallierten Karten europäischer Länder sowie vielen Innovationen für eine verbesserte und komfortable Navigation IQ Routes -
Intelligente Routenberechnung aus aktuellsten Karten unter Berücksichtigung verschiedener Umweltfaktoren wie Tag, Uhrzeit,
 
Straßenabschnitt, Durchschnittsgeschwindigkeiten etc.
Fahrspurassistent für komplizierte Spurenführung, zwei Ausfahrten in einer Ansicht und verbesserte Gebietsabdeckung Text-to-Speech zum Ansagen von Straßennamen und Verkehrshinweisen für einen konzentrierten Blick auf die Fahrbahn und ein entspanntes Fahren
 
Lieferumfang:
XL IQ Routes Edition Europe 42 Traffic, EasyPort-Halterung, USB-Kabel, Autoladegerät, Dokumentation, RDS/TMC-Verkehrsinfo-Empfänger
 
";2;False;0;;;"TomTom XL IQ RoutesTM-Edition Europe ";tomtom-xl-iq-routestm-edition-europe;True;True;P-1950;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;164.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39986,5911689815;66;4;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000264-tomtom-xl-iq-routestm-edition-europe.jpg;;;1;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Trekstor DataStation maxi g.u 500 GB ";"Trekstor DataStation maxi g.u 500 GB USB 2.0 ";"

Trekstor DataStation maxi g.u Externe Festplatte 500 GB USB 2.0

 
 
 
Optimale Speicherplatzerweiterung
Die DataStation maxi g.u ist die perfekte Lösung für das tägliche Backup oder die Speicherplatzerweiterung Ihres PCs.
Die externe 3,5“ Festplatte bietet ausreichend Platz zum Speichern und Archivieren der heimischen
Musik- und Videosammlung, digitaler Fotos oder anderer Dateien.
Schnell und bedienungsfreundlich
Mit dem Hi-Speed USB 2.0 Anschluss bietet die DataStation maxi g.u einen schnellen Datentransfer.
Die Festplatte ist zudem bereits vorformatiert und ohne Treiber sofort betriebsbereit.
Unterstützt werden alle gängigen Dateisysteme von Windows®, Linux® und Mac® OS X, sowie die Betriebssysteme Microsoft Windows® 2000 / XP/ Vista,
Mac® OS X ab 10.3 und Linux® ab Kernel 2.6.x. Die Festplatte wird über das mitgelieferte Netzteil mit Strom versorgt.
Der Ein-/Ausschalter am Festplattengehäuse verhindert überflüssigen Stromverbrauch.
Inklusive Nero Software „BackItUp2 Essentials“
Die ebenfalls im Lieferumfang enthaltene Nero Software rundet das Bild der mobilen, externen Festplatte perfekt ab.
Mit Nero BackItUp2 Essentials können Sie Backups Ihrer Daten sehr einfach planen.
So können einzelne Dateien oder ganze Laufwerke gesichert werden.
Um die Datenmenge gering zu halten, komprimiert die Software die Backups direkt „on the fly“.
Auf Wunsch lassen sich die gesicherten Daten auch per Passwortschutz vor unbefugtem Zugriff schützen.
 
Lieferumfang: Externes Festplattenlaufwerk, USB 2.0-Kabel, Netzteil, Schnellinstallationsanleitung
";2;False;0;;;Trekstor DataStation maxi g.u;trekstor-datastation-maxi-gu-500-gb;True;True;P-2650;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;99.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39982,6066203704;15;2;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000129-trekstor-datastation-maxi-gu-1tb.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Canon Digital IXUS 100 IS Digitalkamera schwarz;"Canon Digital IXUS 100 IS Digitalkamera schwarz ";"

Canon Digital IXUS 100 IS Digitalkamera schwarz

12 Megapixel, 3-fach opt. Zoom, 2,5""Display, HDMI, SLIM
 
Die Digital Ixus 100 IS präsentiert sich im atemberaubend-exquisiten, nur 18,4 Millimeter flachen Edelstahlgehäuse. Sie ist in den vier Farben Silber, Schwarz, Gold und Rot erhältlich.
 
Ob großformatige Fotoprints oder gezielte Ausschnittvergrößerungen: Die hohe Auflösung von 12,1 Megapixeln sorgt für eine überzeugende Detailwiedergabe.
 
Für hohe Geschwindigkeit und exzellente Bildqualität mit brillanten Farben und minimiertem Bildrauschen steht der aktuelle Canon-Bildprozessor DIGIC 4.
12,1 Megapixel Sensor
3-fach optisches Zoom
Großes hochauflösendes 2,5 Zoll PureColor LCD II
Superschlank; HD-Movie und HDMI-Anschluß  mehr Details im Film
 
Lieferumfang:
Digital IXUS 100 IS, Trageriemen, Akku, Akku-Ladegerät, USB-Kabel, Video-Kabel
";2;False;0;;;"Canon Digital IXUS 100 IS Digitalkamera ";canon-digital-ixus-100-is-digitalkamera-schwarz;True;True;P-1690;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;219.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39964,877037037;"56;2095";25;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000251-canon-digital-ixus-100-is-digitalkamera-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000252-canon-digital-ixus-100-is-digitalkamera-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000253-canon-digital-ixus-100-is-digitalkamera-schwarz.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Apple iPod Touch 32 GB schwarz;"Apple iPod Touch 32 GB schwarz mit integrierter WiFi Funktion ";"
Apple iPod Touch 32 GB schwarz mit integrierter WiFi Funktion

Der iPod touch kann alles, was du am iPod toll findest. Und noch vielmehr. Schlankes neues Design. Mit seinem fantastisch flachen Edelstahl-Design liegt der iPod touch mit dem 3.5 Zoll Touch-Display jetzt noch besser in der Hand. Mobil im Spiel. Durch revolutionäre Technologien wie das Multi-Touch-Display, der Beschleunigungssensor und 3D-Grafiken macht das Spielen auf dem iPod touch besonders viel Spaß. Schlaue Musik Mit der neuen Funktion ""Genius"" wird der iPod touch zu Deinem superintelligenten, persönlichen DJ.
 
Nur ein paar Fingertipps, und Genius erzeugt eine Wiedergabeliste mit Songs Deiner Mediathek, die gut zusammenpassen. Internet überall Internetzugang überall, wo ein drahtloses Netzwerk zur Verfügung steht, damit Sie immer mit dabei sind. Multitouch-Oberfläche: Die revolutionäre Technologie des iPhone und die Software Version 3.1 stecken in diesem genialen iPod. Das brillante Breitformat-Display rückt Ihre Videos und Spiele ins beste Licht und dank OpenGL sehen die Spiele jetzt noch besser aus Surfen Sie mit Safari im Web und sehen Sie YouTube Videos auf dem iPod mit integrierter Wi-Fi Funktionalität an. Mit Ihrem iPod touch können Sie im iTunes Wi-Fi Music Store nach Songs suchen, Hörproben abspielen und Titel kaufen.
 
Lieferumfang: iPod touch, Ohrhörer, USB 2.0 Kabel, Kurzanleitung
 
Schlankes neues Design
Mit seinem fantastisch flachen Edelstahl-Design liegt der iPod touch so gut in der Hand wie nie zuvor. Ebenfalls Eindruck machen der neue Lautstärkeregler und der integrierte Lautsprecher.
 
Spiele
Speziell auf die iPod touch Technologie zugeschnittene Spiele sind nur noch einen Fingertipp entfernt. Stöbere in hunderten von Spielen im App Store direkt auf Deinem iPod touch, und wenn Du gefunden hast, was Du suchst, kannst Du es einfach laden und dann kann es losgehen.
 
Steuerung per Fingertipp
Viele Spiele auf dem iPod touch nutzen die Multi-Touch-Technologie für besonders exakte Fingertipp-Steuerung der verschiedenen Spielelemente. Beim Schach ziehst Du mit dem Finger die Figuren, bei Würfelspielen bewegst Du die Würfel. Durch Ziehen mit zwei Fingern kannst Du die Anzeige vergrößern und verkleinern, Deine Figur nach links oder rechts drehen, und durch einfaches Antippen triffst Du eine Auswahl.
 
Musik
Blättere in den Albumcovern Deiner Musiksammlung. Erstelle immer wieder neue Genius Wiedergabelisten und erweitere Deine Sammlung aus dem iTunes Wi-Fi Music Store überall, wo ein Wi-Fi-Hotspot in der Nähe ist.
 
Mit Cover Flow lebt das Flair einer CD- oder Plattensammlung wieder auf. Wer erinnerst sich nicht an das Gefühl beim Durchblättern der Sammlung? Das gibt es jetzt auch auf dem iPod touch: einfach iPod drehen, durch die Cover blättern, ein Album auswählen, fertig. Ein Fingertipp aufs Cover, und schon siehst Du die Titelliste, ein weiterer Tipp spielt die Musik ab, und dabei kannst Du sogar die Songtexte anzeigen.
 
Ein Musikgenie
Stell Dir vor, Du hörst einen Song. Toll wären jetzt andere Titel, die gut dazu passen. Was machst du? Ganz einfach: Du verwendest die neue Funktion ""Genius"". Diese findet die Songs in Deiner Mediathek, die gut zusammenpassen. Du erhältst eine Genius Wiedergabeliste, die Du sofort anhören, sichern oder sogar aktualisieren kannst. Verlass Dich also auf den Genius von iTunes, wenn Du einen Mix willst, auf den Du selbst nicht gekommen wärst.
 
Lautsprecher integriert
Mit dem integrierten Lautsprecher kannst Du Musik und Gespräche ohne Kopfhörer hören – perfekt für zwangloses Hörvergnügen.

Längere Batterielaufzeit
Jetzt kannst Du noch länger rocken (und ansehen und spielen). Der iPod touch hält bis zu 36 Stunden bei Musik oder bis zu 6 Stunden bei Videos durch. Das reicht für drei oder vier Filme zwischen den Ladevorgängen.
 
Internet
Surfe im Internet mit Wi-Fi. Du kannst detailgenaue HTML-E-Mails mit Anlagen empfangen und Wegbeschreibungen und aktuelle Verkehrsinformationen abrufen. Auch als YouTube-Fan entgeht Dir nichts.
 
Überall ins Internet
Der iPod touch ist der einzige iPod mit kabellosem 802.11b/g Internetzugriff. Bei bestehender Wi-Fi-Verbindung kannst Du im Internet surfen und Nachrichten lesen, Sportergebnisse sehen, Rechnungen bezahlen und online einkaufen.
 
Wer suchet, der findet
Der iPod touch synchronisiert Deine Lesezeichen vom PC oder Mac, sodass Du ruck zuck auf Deine Lieblingsseiten zugreifen kannst. Die Google- und Yahoo!-Suche ist schon integriert, sodass Du im Web schnell findest, was Du suchst.
 
Zoom mit Aussicht
Jeden beliebigen Ausschnitt einer Webseite kannst Du vergrößern, indem Du mit dem Finger darauf tippst oder mit zwei Fingern die Anzeige aufziehst. Websites lassen sich im Hoch- oder Querformat anzeigen: einfach den iPod touch um 90 Grad drehen, und schon wird auch die Darstellung der Website gedreht.
 
Eigene Weblinks
Für häufig besuchte Websites, etwa die einer Zeitung, eines Blogs oder eine Sport-Website, kannst Du einfach ein Symbol auf dem Home-Bildschirm erstellen. Deine Lieblingsseiten sind über mit Safari erstellte Weblinks nur einen Fingertipp entfernt.
 
Rock 'n' Run mit Nike+
Im iPod touch ist kabellose Unterstützung für Nike + iPod integriert. Du brauchst nur einen Nike + iPod Sensor in Deinem Schuh, und schon kann's losgehen.
 
Das optimale Lauftraining
Im iPod touch ist jetzt Unterstützung für Nike + iPod integriert. Einfach den Nike + iPod Sensor (separat erhältlich) in den Nike+ Laufschuh einsetzen, und es kann losgehen. Der Sensor überträgt die Laufdaten drahtlos an den iPod touch – er erfasst die gelaufene Zeit, die zurückgelegte Strecke und die verbrauchten Kalorien. Außerdem gibt er Dir gesprochenes Feedback zu Deinen Trainingsfortschritten.
 
Das optimale Fitnesstraining
Diese Funktion kann auch zusammen mit neuen, in vielen Fitnessstudios vorhandenen Geräten für das Ausdauertraining gekoppelt werden. Suche einfach nach mit Nike + iPod kompatiblen Laufbändern, Elliptical Trainern, Steppern und Hometrainern.
";2;False;0;;;Apple iPod Touch 32 GB;apple-ipod-touch-32-gb-schwarz;True;True;P-1260;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;277.9000;277.9000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39915,3405439815;43;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000141-apple-ipod-touch-16-gb-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000142-apple-ipod-touch-16-gb-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000143-apple-ipod-touch-16-gb-schwarz.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Apple iPod shuffle 4 GB silber;Apple iPod shuffle 4GB silber;"
Apple iPod shuffle 4GB silber
 
 
Der kleinste iPod der Welt
 
 
Um den kleinsten iPod der Welt zu bauen, haben wir die Steuerung vom iPod shuffle in das Ohrhörerkabel integriert.
So wird der iPod shuffle noch kleiner und die Steuerung ist genau da, wo du sie einfach erreichst.
Wenn du einen Song abspielen, anhalten oder überspringen möchtest,
musst du nicht lange nach dem iPod shuffle suchen - greif einfach zum Kabel und drücke auf eine der Tasten.
Dieser Entertainment-Winzling sagt Ihnen auf Knopfdruck, welchen Titel er gerade abspielt
Organisieren Sie Ihre Musik in verschiedenen Wiedergabeslisten
Dank eines stabilen, integrierten Clips lässt sich der iPod shuffle fast überall befestigen.
Lassen Sie sich aufs Ungewisse ein: Verwenden Sie den Schalter für die Zufallswiedergabe,
um den Inhalt Ihres iPod shuffle neu zu mischen.
Lieferumfang: Apple Earphones mit Remote Fernbedienung
 
iPod shuffle - In leuchtenden neuen Farben spricht Musik dich richtig an
 
Der kleinste iPod der Welt
Um den kleinsten iPod der Welt zu bauen, haben wir die Steuerung vom iPod shuffle in das Ohrhörerkabel integriert. So wird der iPod shuffle noch kleiner und die Steuerung ist genau da, wo du sie einfach erreichst. Wenn du einen Song abspielen, anhalten oder überspringen möchtest, musst du nicht lange nach dem iPod shuffle suchen - greif einfach zum Kabel und drücke auf eine der Tasten.
 
Der erste iPod, der mit dir spricht
Die VoiceOver Funktion ist mit Sicherheit der nächste Hit auf dem iPod shuffle.1 Angenommen du hörst einen Song und willst wissen, wie er heißt oder von wem er ist: Einfach Knopf drücken und VoiceOver sagt es dir. Sogar die Namen deiner Wiedergabelisten verrät es dir. Und wenn die Batterie aufgeladen werden muss, sagt VoiceOver dir das auch.
 
Leichtbedienung
Die Steuerung befindet sich am Kabel des rechten Ohrstöpsels. Dadurch, dass die Steuerung jetzt hier angebracht ist, kannst du deine Musiktitel durchsuchen - und die VoiceOver Funktion aktivieren - ohne vom Joggen, Rad fahren oder anderen Aktivitäten abgelenkt zu werden. Der iPod shuffle wird mit dieser einfachen Steuerung geliefert. Du kannst aber auch Kopfhörer mit ähnlichen Bedienelementen von Herstellern wie Scosche, Klipsch, V-MODA und Belkin verwenden.
 

Dein Musikarchiv. Für unterwegs
Der iPod shuffle kommt jetzt mit 2 GB oder 4 GB. Mit dem 4 GB Modell hast du jede Menge Platz, um Musik für viele Stunden - bis zu 1.000 Songs - zu speichern.2 Damit bist du im Fitnessstudio oder auf dem Weg zur Arbeit bestens gerüstet. Außerdem kannst du jetzt mehrere Wiedergabelisten und auch Hörbücher verwenden.
 
Mehrere Wiedergabelisten
Wahrscheinlich hast du dir in iTunes schon einige Wiedergabelisten zusammengestellt. Eine für unterwegs. Eine fürs Fitnessstudio. Eine zum Chillen. Jetzt kannst du deine Wiedergabelisten auf dem Computer mit dem iPod shuffle synchronisieren und hast immer genau den richtigen Mix - egal, was du gerade machst oder in welcher Stimmung du bist. VoiceOver nennt dir den Namen jeder Wiedergabeliste. So kannst du ganz leicht zwischen ihnen wechseln und genau die auswählen, nach der dir gerade ist.
 
Farbe bekennen
Mit dem flachen, robusten Gehäuse aus eloxiertem Aluminium ist der iPod shuffle immer das passende Accessoire. In leuchtendem Pink, Blau, Grün, Schwarz oder Silber ist er ein echtes Fashion Statement. Ganz neu dabei: der iPod shuffle Special Edition in poliertem Edelstahl (So werden Rockstars nun mal behandelt). Sogar der iPod shuffle Clip sieht stylish aus. Er klemmt sicher an Hemd, Jacke, Sportzeug oder am Rucksack. So wird der iPod shuffle zum perfekten Fashtech-Accessoire. Und klar, natürlich ist noch Platz für eine persönliche Gravur.

Mehrsprachig
Ein französisches Chanson. Ein spanischer Bolero. Eine italienische Arie. Dein Musikarchiv enthält Musik aus allen Ländern der Welt. Deshalb spricht VoiceOver 20 Sprachen und kann die Namen von Songs und Interpreten mit der richtigen Aussprache sprechen.
 
Zufall oder kein Zufall?
Der Schalter am iPod shuffle hat drei Einstellungen. Links wird deine Musik zufällig durcheinander gewürfelt. In der Mitte werden deine Songs in der normalen Reihenfolge gespielt. Rechts wird der iPod shuffle ausgeschaltet.
";2;False;0;;;Apple iPod shuffle Tragbarer MP3-Player 4 GB 3. Generation;apple-ipod-shuffle-4-gb-silber;True;True;P-1210;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;79.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39908,3107986111;40;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000220-apple-ipod-shuffle-4-gb-silber.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000221-apple-ipod-shuffle-4-gb-silber.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000222-apple-ipod-shuffle-4-gb-silber.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"AVM FRITZ!Fon 7150 ";"AVM FRITZ!Fon 7150 Fritz!Box Router +Telefon + VOiP ";"
FRITZ!Fon 7150 vereint VoIP-/Festnetz- Telefonanlage, DSL-Modem, WLAN-Router und DECT-Telefon in einem Gerät.

FRITZ!Fon 7150 kann alles, was eine FRITZ!Box auszeichnet und bringt noch ein DECT-Mobilteil mit. Das Multitalent bietet Festnetz- und Internettelefonie, schnelles Surfen im Internet und kabellosen DSL-Zugang in einem Gerät. Telefongespräche können wahlweise über Internet (Voice over IP) oder Festnetz geführt werden – auch bei ausgeschaltetem Computer. Das zugehörige Mobilteil bietet alle Vorteile der Schnurlostelefonie über DECT. Die Anmeldung von weiteren Mobilteilen an der Basisstation ist problemlos möglich. Bereits vorhandene ISDNTelefone oder ISDN-TK-Anlagen lassen sich ohne weiteres an FRITZ!Fon 7150 anschließen.
 
Durch die Router-Funktion erhalten alle PCs im Netzwerk Zugang zum Internet über LAN und WLAN. Die WLAN-Funkverbindungen sind ab Werk mit dem sicheren WPA-Standard verschlüsselt und dank der Stick & Surf-Funktion von AVM erfolgt die Konfiguration automatisch. Über die USB-Schnittstelle können auch USB-Drucker und -Speichermedien für die gemeinsame Nutzung komfortabel vernetzt werden. Die Hard- und Software-Firewall schützt alle Geräte im Netzwerk vor Angriffen von außen. Zusätzliche Komfortfunktionen der FRITZ!Fon 7150 wie Nachtschaltung, Klingelsperre oder ein Mailservice ergänzen die Komplettlösung für Telefonie und Internet.
 
Internettelefonie mit Festnetzqualität
Intelligentes Codec Management sorgt für eine konstante Sprachqualität beim VoIPen. Dank Bandbreitenmanagement surfen Sie gleichzeitig mit optimaler Qualität im Internet, ohne dass Internettelefonate gestört werden. Mit zwei Mobilteilen an der Station sind auch zwei Gespräche gleichzeitig schnurlos möglich – eines als Festnetz- und eines als Internettelefonat. Neben der exzellenten Sprachqualität bietet FRITZ!Fon 7150 auch bei Internettelefonie ISDN-Leistungsmerkmale wie Makeln, Anklopfen, Rufnummernanzeige, Direktruf oder Dreierkonferenz. Bis zu 10 verschiedene VoIP-Rufnummern – auch unterschiedlicher Provider – lassen sich speichern.
 
Schnurloses Telefonieren mit DECT-Komfort
Das DECT-Mobilteil bietet neben einem Farbdisplay mit grafischer Darstellung und einem digitalen Anrufbeantworter ein Telefonbuch für 200 Einträge. Sowohl das Adressbuch als auch die Anrufliste lassen sich bequem über das Mobilteil pflegen. Das ist mit einer Gesprächszeit von bis zu 17 Stunden selbst langen Telefonaten gewachsen. Über das bei DECT eingesetzte GAP-Profil lassen sich bis zu fünf weitere Mobilteile anmelden.
 
WLAN – sicher und schnell
FRITZ!Fon 7150 bietet bereits ab Werk eine sichere WLAN-Verbindung dank aktivierter WPA-Verschlüsselung. Mit der von AVM entwickelten Stick & Surf-Technologie wird der Start ins kabellose Surfen vereinfacht. Sobald der FRITZ!WLAN Stick in den USBHost der FRITZ!Fon 7150 gesteckt wird, werden die Konfigurations- und Sicherheitseinstellungen automatisch zwischen beiden Geräten abgeglichen. FRITZ!Fon 7150 unterstützt die neuesten WLAN-Standards und ermöglicht Verbindungen bis zu 125 MBit/s. Auf Wunsch lässt sich WLAN per Tastendruck an der Basisstation abschalten.
 
";2;False;0;;;"AVM FRITZ!Fon 7150 (Fritz!Box Router +Telefon + VOiP) ";avm-fritzfon-7150;True;True;P-2760;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;169.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39907,7783680556;20;34;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000218-avm-fritzfon-7150.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000219-avm-fritzfon-7150.jpg;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"AVM FRITZ!Fon MT-D VoIP Dect-Telefon ";"AVM FRITZ!Fon MT-D VoIP Dect-Telefon ";"
FRITZ!Fon MT-D: HD-Telefonie und komfortable Internetdienste mit DECT.
Telefonieren Sie mit dem Schnurlostelefon FRITZ!Fon MT-D in bestechender Qualität über das Internet und nutzen Sie komfortable Webdienste. Als intelligentes Telefon der neuesten DECT-Generation vereint das FRITZ!Fon den Komfort der schnurlosen Telefonie mit den Qualitäts- und Leistungsmerkmalen der Internettelefonie (VoIP) in einem Gerät.
 
Bei der Internettelefonie mit einem FRITZ!Fon wird durch HD-Telefonie (High Definition) ein brillantes, natürliches Klanggefühl erreicht. Sprache lässt sich mit dem FRITZ!Fon in ihrem gesamten Frequenzspektrum wiedergeben, was die Klangqualität von Festnetzverbindungen deutlich übertrifft.
 
FRITZ!Fon unterstützt die übertragung großer Bandbreiten. Dies ermöglicht neben HD-Telefonie auch die Nutzung komfortabler Internetdienste wie den Empfang von E-Mails, Podcasts, RSS-Feeds und Internetradio.
 
Die FRITZ!Box-Modelle FRITZ!Box Fon WLAN 7390, 7320, 7270 oder 7240 stellen mit der integrierten DECT-Basisstation, mehreren Anrufbeantwortern und einem Telefonbuch mit 300 Einträgen den idealen Partner für das FRITZ!Fon dar. Mit der umfangreichen Prozessor- und Speicherausstattung ist auch der Grundstein für neue Anwendungen gelegt. Denn das FRITZ!Fon ist lernfähig: Als eines der ersten intelligenten Schnurlostelefone wird es auch künftig per Firmware-Updates aktualisiert und um neue Funktionen erweitert werden können.
 
Umfangreicher Komfort
Das FRITZ!Fon MT-D ist mit zahlreichen Komfortfunktionen ausgestattet. Dazu zählen Lauthören und Freisprechen in HD-Qualität sowie ISDN-Leistungsmerkmale wie Namensanzeige bei bekannten Rufnummern, Halten, Makeln, Anklopfen, Rufumleitung oder Dreierkonferenz. Die Internettelefonie in HD-Qualität lässt sich so in ihrem vollen Umfang und Komfort nutzen, ohne dass der Computer eingeschaltet sein muss. FRITZ!Fon informiert zudem aktiv über unbeantwortete Anrufe, Nachrichten auf dem Anrufbeantworter und zeigt eingegangene E-Mails an. An der DECT-Basisstation der FRITZ!Box Fon WLAN 7390, 7320, 7270 und 7240 lassen sich bis zu 6 FRITZ!Fon-Handgeräte oder andere DECT-Telefone anmelden. Die Erstinstallation und individuelle Einstellungen erfolgen dabei bequem über einfache Assistenten.
 
FRITZ!Box als idealer Partner
Das FRITZ!Fon MT-D kann als Mobilteil an jeder DECT-Basisstation eingesetzt werden. Im Zusammenspiel mit der FRITZ!Box Fon WLAN 7390, 7320, 7270 oder 7240 kann jedoch das volle Spektrum der Möglichkeiten beim Telefonieren und Surfen über das Internet ausgenutzt werden. Die FRITZ!Box Fon WLAN 7390 zum Beispiel vereint eine bisher nicht erreichte Vielfalt in einem Gerät: VDSL- und ADSL-Unterstützung, DECT-Basisstation fürs schnurlose Telefonieren sowie WLAN N für die optimale Datenübertragung.
 
Über den Mediaserver sind gespeicherte Filme, Musik und Bilder auch bei ausgeschaltetem Computer im gesamten Netzwerk verfügbar. Darüber hinaus kann der Online-Speicher wie eine lokale Festplatte genutzt werden. So wird die FRITZ!Box Fon WLAN 7390 zur idealen Plattform für vernetzte Anwendungen wie IPTV, Video on Demand oder Mediastreaming.
 
Bedienung
- Einfach einschalten und Suchtaste auf FRITZ!Box drücken.
 
- Einfache Bedienung über intuitives Menü.
 
- Telefonbuch komfortabel über FRITZ!Box-Oberfläche einrichten und anzeigen.
 
- In FRITZ!Box integrierte Anrufbeantworter einfach am FRITZ!Fon MT-D einrichten und abhören.
 
- Blinkende Leuchtdiode signalisiert eingegangene Anrufe, neue Nachrichten auf dem Anrufbeantworter und neue E-Mails.
 
- Große Schrift und große Tasten.
";2;False;0;;;"AVM FRITZ!Fon MT-D VoIP Dect-Telefon ";avm-fritzfon-mt-d-voip-dect-telefon;True;True;;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;49.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39907,7759837963;20;34;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000213-avm-fritzfon-mt-d-voip-dect-telefon.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000214-avm-fritzfon-mt-d-voip-dect-telefon.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000215-avm-fritzfon-mt-d-voip-dect-telefon.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"AVM FRITZ!WLAN USB Stick ";"AVM FRITZ!WLAN USB Stick - mit Stick & Surf Wireless LAN ";"
AVM FRITZ!WLAN USB Stick - mit Stick & Surf Wireless LAN
 
Allgemein / Breite [cm]: 2
Allgemein / Formfaktor: Extern
Allgemein / Gerätetyp: Netzwerkadapter
Allgemein / Gewicht [g]: 10
Allgemein / Höhe [cm]: 1.1
Allgemein / Schnittstellentyp (Bustyp): Hi-Speed USB
Allgemein / Tiefe [cm]: 5.3
Antenne / Antenne: Intern eingebaut
Erweiterung-Konnektivität / Verbindungen: 1 x Hi-Speed USB - USB Typ A, 4-polig
Kopf / Hersteller: AVM
Kopf / Kompatibilität: PC
Kopf / Modell: USB Stick
Kopf / Paketierte Menge: 1
Kopf / Produktlinie: AVM FRITZ!WLAN
Netzwerk / Anschlusstechnik: Drahtlos
Netzwerk / Data Link Protocol: IEEE 802.11n;IEEE 802.11b;IEEE 802.11g
Netzwerk / Datenübertragungsrate [Mbps]: 150
Netzwerk / Frequenzband: 2.4 GHz
Netzwerk / Leistungsmerkmale: Stromversorgung über USB;Wi-Fi Protected Setup (WPS);Firmware aktualisierbar
Netzwerk / Produktzertifizierungen: IEEE 802.11n;IEEE 802.11g;USB 2.0;USB 1.1;IEEE 802.11b;IEEE 802.11i
Netzwerk / Statusanzeiger: Link/Aktivität
 
Software-Systemanforderungen / Erforderliches Betriebssystem:
 
Microsoft Windows XP SP2;Microsoft Windows 7;Microsoft Windows Vista
Software-Systemanforderungen / Software inbegriffen: Treiber & Utilities
Verschiedenes / Encryption Algorithm: WPA2;128-Bit WEP;64-Bit WEP;WPA
Verschiedenes / Enthaltene Kabel: 1 x USB-Kabel ( extern ) - 90 cm
";2;False;0;;;"AVM FRITZ!WLAN USB Stick N Standard 300MBit/Sek ";avm-fritzwlan-usb-stick;True;True;P-2720;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;39.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39907,7691203704;19;34;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000208-avm-fritzwlan-usb-stick.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000209-avm-fritzwlan-usb-stick.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000210-avm-fritzwlan-usb-stick.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Navigon Schutztasche 21|12|22|13|23 Serie ";"Navigon Schutztasche 21|12|22|13|23 Serie ";"

Navigon Schutztasche 21|12|22|13|23 Serie

 
Diese Tasche schützt Ihren PNA vor Schmutz, Kratzern und Stößen.
Einfach den PNA in die Tasche stecken. Textiltasche mit Zipper
";2;False;0;;;;navigon-schutztasche-2112221323-serie;True;True;P-2140;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;24.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39887,5982523148;68;14;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000197-navigon-schutztasche-2112221323-serie.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Hama MP3-Tasche für Sansa Clip;Hama MP3-Tasche für Sansa Clip;

Hama MP3-Tasche für Sansa Clip

passgenaue Silikontasche, sitzt wie eine zweite Haut
Farbe: Transparent
Ausstattung:
rutschfeste Oberfläche
Aussparung für Kabelverbindungen
;2;False;0;;;Hama MP3-Tasche für Sansa Clip;hama-mp3-tasche-fuer-sansa-clip;True;True;P-1580;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;14.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39881,6482638889;52;8;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000196-hama-mp3-tasche-fur-sansa-clip.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Apple iPod Nano 16 GB silber;Apple ipod nano 16 GB silber mit Kamera;"
Apple ipod nano 16 GB silber mit Kamera
 
Der neue iPod nano. Jetzt mit Videokamera, Gehäuse aus poliertem Aluminium und einem größeren Display und dem neuen FM Radio mit Live-Pause.
 
Neues gebogenes Design, der dünnste iPod, den es je gab mit neun Farben zu Auswahl
Die Bedieung optimiert: ein einziges Handschütteln und ein anderes Lied wird gespielt
Die neue Funktion ""Genius"" findet die Songs in Ihrer Mediathek, die besonders gut zusammenpassen, und erstellt daraus eine Genius Wiedergabeliste.
Viele Abspielformate: z.B. MP3, AAC, Apple Lossless, AIFF, WAV, H.264, MPEG-4
Lieferumfang: iPod Nano, Ohrhörer, USB 2.0 Kabel, Dock-Adapter, Dokumentation, iTunes 9.0
 
Vom beliebtesten Musikplayer der Welt gibt es jetzt noch mehr zu sehen.Vom beliebtesten Musikplayer der Welt gibt es jetzt noch mehr zu sehen.Ein Wettrennen mit Einkaufswagen. Der große Food Fight um das Essen in der Mensa. Jetzt kannst du all das mit der iPod nano Videokamera festhalten. Nimm hochwertige Videos im Hoch- oder Querformat auf, die du ganz einfach ins Web stellen oder an Freunde mailen kannst. Über das im iPod nano integrierte Mikrofon wird das Audiomaterial aufgenommen, das du dann beim Abspielen über die integrierten Lautsprecher hörst.
 
nano macht video
Der neue iPod nano. Jetzt mit Videokamera, Gehäuse aus poliertem Aluminium und einem größeren Display. Und dem neuen FM Radio mit Live-Pause.
 
Mach überall zur Filmkulisse
Den iPod nano gibt's jetzt mit integrierter Videokamera, mit der Sie überall alles spontan festhalten und dann mit deinen Freunden im Internet teilen können. Diese Videokamera ist so klein, dass Sie sie überallhin mitnehmen können.
 
Videoaufnahme. So nano kann Video sein
Blättern Sie durch das Menü zur Videokamera und schon können Sie Videos im Hoch- oder Querformat aufnehmen - ideal zum Mailen oder Posten auf Facebook oder MobileMe. Mit dem integrierten Mikro können Sie auch Ton aufnehmen. Wenn Sie dann Ihr Video auf dem iPod nano abspielen, hören Sie den Ton gleich dazu. Damit wird Ihr Immer-dabei-Musikplayer zur Immer-dabei-Videokamera.
 
Special Effects Abteilung inklusive
15 tolle Videoeffekte geben Ihren Videos richtigen Hollywood-Touch. Blättern Sie durch die Effekte, wählen Sie den passenden aus, z. B. Filmkörnung oder Bewegungsunschärfe, und dann Kamera ab! Wenn Sie fertig sind, synchronisieren Sie den iPod nano mit Ihrem Computer und iPhoto (oder eine andere Foto-Software) wird geöffnet. Jetzt brauchen Sie Ihren Videohit nur noch zu mailen oder auf YouTube oder Facebook zu posten.
 
Synchronisieren - Teilen - Und noch mehr Videos auf YouTube laden
Wenn Sie den iPod nano an Ihren Mac anschließen, wird iPhoto geöffnet und alle mit dem iPod nano gemachten Videos werden mit Ihrem Computer synchronisiert. Auf dem PC geht das mit Ihrer Fotosoftware genauso einfach. Auf einem Mac können Sie Ihre Videos dann direkt in iPhoto durchsuchen und bearbeiten. Die Dateigrößen der Videos sind perfekt geeignet, um sie auf YouTube hochzuladen oder an Freunde zu mailen.
 
Das ist Genius
Steuern Sie Genius selbst. Oder Sie lassen ihm einfach freien Lauf. Egal, wofür Sie sich entscheident, Genius durchsucht Ihr Musikarchiv nach Songs, die gut zusammenpassen.
 
Genius Wiedergabelisten
Angenommen Sie haben einen Lieblingssong und möchten weitere Titel hören, die gut dazu passen. Ein paar Klicks auf den iPod nano und Genius sucht anhand dieses Songs weitere Titel in Ihrem Musikarchiv und erstellt eine Genius Wiedergabeliste für Sie. Sie können sie sich sofort anhören, für später speichern oder aktualisieren und nochmal gucken, was dabei rauskommt. Wenn Sie Songmixes suchen, an die Sie selbst nie gedacht hätten, dann überlassen Sie das ruhig Genius.
 
Genius Mixe
Und es gibt noch eine tolle Möglichkeit, eine ganz persönliche Songsammlung auf den iPod nano zu bekommen und Genius alles für Sie erledigen zu lassen: Die Genius Mixe. Sie müssen dafür nur den iPod nano mit iTunes synchronisieren. Genius durchsucht dann automatisch Ihr Musikarchiv nach Songs, die gut zusammenpassen und erstellt bis zu 12 Genius Mixe. Diese genrebasierten Mixe sind wie Radiosender, die nur Ihre Musik spielen. So entdecken Sie Songs wieder, die Sie schon ewig nicht mehr gehört haben oder welche, die Sie schon ganz vergessen hatten.
 
Das ist so Cover Flow
Blättern Sie mit Cover Flow durch Ihre Alben, um ganz schnell den richtigen Song zu finden. Oder halten Sie die Mitteltaste gedrückt, um das Albumcover umzudrehen und die Songs zu sehen. Wenn Sie den gewünschten Song gefunden haben, drücken Sie auf die Mitteltaste, um ihn zu Ihrer On-the-Go-Wiedergabeliste hinzuzufügen.
 
Zum Mischen schütteln
Hören Sie Songs einfach mal nach dem Zufallsprinzip. Einfach die Schüttelfunktion aktivieren, den iPod nano kurz schütteln und schon springt er zu irgendeinem anderen Song. Lassen Sie sich überraschen, was der iPod nano als nächstes für Sie auflegt.
 
Radio hören - Radio anhalten. Radio weiterhören
Der neue FM Tuner zeigt Ihnen die Namen von Songs und Interpreten. Und mit der fantastischen neuen Live-Pause Funktion ist Radio hören noch besser als Radio hören.
 
FM Radio. Noch eine Möglichkeiten zu rocken
Im Radio läuft immer gute Musik. Und mit dem FM Tuner können Sie Ihre Lieblingssendungen jetzt auf dem Weg zur Arbeit hören oder neue Musik entdecken, während Sie im Fitnessstudio rocken. Sie sehen sogar was und wen Sie gerade hören.
 
Mit Live-Pause nie mehr einen Beat verpassen
Angenommen Sie müssen Ihre Lieblingssendung im Radio einmal kurz unterbrechen. Ein Klick auf den iPod nano und schon ist Pause. Noch ein Klick und Sie hören die Sendung weiter. Sie können sogar bis zu 15 Minuten zurückspulen und dann vorspulen, um wieder live dabei zu sein.
 
VoiceOver. Spricht jeden an
VoiceOver sagt Ihnen die Namen von Titel und Interpreten der Songs, die Sie gerade hören. Und zwar so gut, dass Sie überrascht sein werden.
 
Lass mal VoiceOver reden
Sie hören einen Song und wollen wissen, wie er heißt oder von wem er ist? Benutzen Sie einfach das Click Wheel oder die Steuerung an den optionalen Apple Earphones mit Fernbedienung und Mikro, damit VoiceOver Ihnen Songtitel und Interpreten sagt, ohne dabei die Musik zu unterbrechen. Sie müssen nicht mehr auf das Display schauen, sondern können sich aufs Joggen oder Radfahren konzentrieren.
 
So funktioniert's
VoiceOver funktioniert ganz einfach. Wir haben hart daran gearbeitet, damit der iPod nano nicht nur spricht, sondern auch genau das Richtige sagt. Alles beginnt mit iTunes und der engen Zusammenarbeit mit dem iPod nano. iTunes liest zunächst die Songinformationen, und verwendet dann das VoiceOver Kit, um Ansagen für Songs, Interpreten und Wiedergabelisten zu erstellen. Sie müssen einfach nur deinen iPod nano mit deinem Computer synchronisieren und schon spricht er mit Ihnen.
 
Das Sprachtalent
Dein Musikarchiv enthält Musik aus allen Ländern der Welt: Chansons aus Frankreich, Sambarhythmen aus Brasilien und Popmusik aus Japan. Zum Glück spricht VoiceOver fließend Songisch.
iTunes wählt automatisch die Sprache und die beste Stimme für die Songtitel und Interpreten aus. Die Software analysiert Songdaten wie Titel, Interpreten und Albuminfos und nutzt dann intelligente Algorithmen, um die richtige Sprache auszuwählen. ""Ya Viene el Sol"" von Ozomatli erkennt iTunes zum Beispiel als spanischen Song - und schon spricht der iPod den Songtitel und Interpreten automatisch auf Spanisch aus. Sie wollen es lieber in einer anderen Sprache hören? Dann können Sie die VoiceOver Sprache für diesen Song natürlich in iTunes ändern.
 
Geht sofort los
Mit dem Nike + iPod Sport Kit und einem integrierten Schrittzähler, das Ihre Fortschritte verfolgt und Sie motiviert, wird das Training mit dem iPod nano nie zur Routine.
 
Der erste Schritt in Richtung Fitness
Der iPod nano ist sowieso schon Ihr ständiger Begleiter, warum sollten Sie ihn also nicht auch als Fitnesstrainer nutzen? Denn jetzt wird er auch zum Schrittzähler. Mit dem integrierten Beschleunigungssensor zählt er Ihre Schritte, damit Sie Ihr Fitnessziel nie aus den Augen verlieren. Sie können eine tägliche Schrittvorgabe festlegen oder ""Immer eingeschaltet"" wählen, damit er jeden Ihrer Schritte zählt. Das macht den iPod nano zum idealen Trainingspartner.
 
Rock'n'Run
Mit dem iPod nano und Ihren Laufschuhen holen Sie alles aus Sich raus. Sehen Sie wie die Minuten verfliegen und Sie Kilometer für Kilometer zurücklegen. Sie bekommen Sprachfeedback in Echtzeit und hören dabei Ihren Lieblingsmusik und den PowerSong, der Sie jedes Mal wieder antreibt, Ihr Bestes zu geben.
 
Rock das Training
Nehmen Sie Nike + iPod mit ins Fitnessstudio und Sie werden Minute für Minute, Kilometer für Kilometer durch mehr als nur Musik motiviert. Schließen Sie den iPod nano an ein Fitnessgerät an, das mit Nike + iPod kompatibel ist. Halten Sie die Geschwindigkeit, die Dauer und die Laufstrecke deines Trainings fest. Mit dem iPod nano wird jeder Besuch im Fitnessstudio zur neuen Herausforderung.
 
Synchronisieren
Wenn Sie fertig sind, schließen Sie den iPod nano an Ihren Mac oder PC an. Ihre Workout-Daten werden dann automatisch von iTunes an nikeplus.com gesendet. Dort können Sie dann alle Ihre Workouts und Läufe überprüfen. Holen Sie außerdem neue Motivation für den nächsten Lauf mit empfohlenen Zielvorgaben, persönlichen Trainingsprogrammen und Karten mit neuen Strecken, die Sie ausprobieren können. Oder tauschen Sie sich mit Läufern aus aller Welt aus.
";2;False;0;;;Apple ipod nano 16 GB schwarz;apple-ipod-nano-16-gb-silber;True;True;P-1380;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;159.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39876,6815625;48;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000087-apple-ipod-nano-8-gb-verschiedene-farben.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000076-apple-ipod-nano-8-gb-verschiedene-farben.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000077-apple-ipod-nano-8-gb-verschiedene-farben.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Griffin Sports Tempo Armband für iPod nano ";"Griffin Sports Tempo Armband für iPod nano ";"

Griffin Sports Tempo Armband für iPod nano  

 
Mit dem Tempo Armband von Griffin ist der iPod Nano sicher geschützt und doch immer erreichbar
Egal, ob Sie wandern, joggen, reiten, Kanu fahren, Fallschirm springen, im Garten werkeln oder sich einfach nur zu Hause entspannen.

Das formschöne, unauffällige Design mit Reflektorstreifen sorgt für hohe Sichtbarkeit. 
Eine Aufwicklung für das Kopfhörerkabel sorgt dafür, dass Kabelsalat vermieden wird. 
Tempo ist mit einer Abdeckung zum Schutz des iPod Displays und einem weichen Innenfutter ausgestattet.
Das Armband ist für alle Größen gut geeignet und in der Waschmaschine waschbar.
";2;False;0;;;"Griffin Tempo Sports Armband ";griffin-sports-tempo-armband-fuer-ipod-nano;True;True;P-1530;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;35.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39876,600787037;51;28;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000195-griffin-sports-tempo-armband-fur-ipod-nano.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Artwizz SeeJacket Crystal Case für iPod Nano 4G;Artwizz SeeJacket Crystal Case für iPod Nano 4G transparent;"

Artwizz SeeJacket Crystal Case für iPod Nano 4G transparent

 
Funktionale Schutzhülle aus Polycarbonat - Kristallklare Schutzhülle, speziell für iPod nano 4G
Hochwertige, robuste und transparente Schutzhülle
Komplettschutz für Vorder- und Rückseite (inkl. Display)
Anschlüsse sind ausgespart
Keine Beeinträchtigung der Bedienbarkeit des iPod nano 4G.
";2;False;0;;;Artwizz SeeJacket Crystal Case für iPod Nano 4G;artwizz-seejacket-crystal-case-fuer-ipod-nano-4g;True;True;P-1440;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;19.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39860,7781828704;51;30;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000194-artwizz-seejacket-crystal-case-fur-ipod-nano-4g.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Belkin F8Z 409 Silikonhülle für Apple iPod Classic ";"Belkin F8Z 409 Silikonhülle für Apple iPod Classic ";"

Belkin F8Z 400 Silikonhülle für Apple iPod Classic

schwarz/blau/rosa 3er-Pack

iPod Classic SILICON SLEEVE 3-PACK Schwarz & Blau & Pink
";2;False;0;;;;belkin-f8z-409-silikonhuelle-fuer-apple-ipod-classic;True;True;P-1430;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;14.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39860,7754166667;51;;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000193-belkin-f8z-409-silikonhulle-fur-apple-ipod-classic.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Garmin DVD City Navigator Europa NT Update 2010;Garmin DVD City Navigator Europa NT Update 2010;"

Garmin DVD City Navigator Europa NT Update 2010

Der City Navigator Europa NT 2010 bietet einen erhöhten Detailgrad
mit über 8 Millionen km Straßenabdeckung in Europa
 
Volle Länderabdeckung für die Baltischen Staaten + erweiterte Straßenabdeckung
von Griechenland, Kroatien, Tschechien, Ungarn, Polen, Slowakei
 
1,2 Millionen POIs und 1 Millionen Städte, Orte und Dörfer,
über 8.000 Campingplätze in West-Europa
Update der zulässigen Höchstgeschwindigkeiten
Lieferumfang: DVD mit City Navigator Europa NT
";2;False;0;;;Garmin DVD City Navigator Europa NT Update 2009;garmin-dvd-city-navigator-europa-nt-update-2010;True;True;P-2020;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;99.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39856,6709722222;67;44;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000192-garmin-dvd-city-navigator-europa-nt-update-2010.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Sony MDR EX 35 LPB.AE Stereo-In-Ear-Kopfhörer schwarz ";"Sony MDR EX 35 LPB.AE Stereo-In-Ear-Kopfhörer schwarz ";"

Sony MDR EX 35 LPB.AE Stereo-In-Ear-Kopfhörer schwarz

 
Leistungsstarke Kopfhörer, hervorragend geeignet als Ersatz für mp3-Player-Kopfhörer der Einstiegsklasse.>Leistungsmerkmale
Hybrid-Silikon-Ohrpolster für sicheren Halt und Langzeit-Tragekomfort
Y-förmiges Kabel mit praktischem Kabel- Reiter zur Vermeidung von Kabelsalat
Frequenzgang: 6-23,000Hz
3,5mm Klinkenanschluss
Kabel: 1,2Y-förmig
 
Zubehör: Ohrpolster, Kabel-Reiter
";2;False;0;;;"Sony MDR EX 35 LPB.AE Stereo-In-Ear-Kopfhörer schwarz ";sony-mdr-ex-35-lpbae-stereo-in-ear-kopfhoerer-schwarz;True;True;P-1500;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;24.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39816,7113541667;51;10;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000187-sony-mdr-ex-35-lpbae-stereo-in-ear-kopfhorer-schwarz.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Creative EP 630 Ohrhörer schwarz ";"Creative EP 630 Ohrhörer schwarz ";"

Creative EP 630 Ohrhörer schwarz

 
Silikon-Ohrpolster schirmen Umgebungsgeräusche effektiv ab und verbessern die Basswiedergabe
Leicht und komfortabel - für maximalen Musikgenuss unterwegs
Sauerstofffreie Kupferkabel für verlustfreie Signalübertragung
Lieferumfang: 1 Paar In-Ear-Ohrhörer mit Silikon-Ohrpolstern,
2 Paar zusätzliche Silikon-Ohrpolster in verschiedenen Größen
";2;False;0;;;"Creative EP 630 Ohrhörer ";creative-ep-630-ohrhoerer-schwarz;True;True;P-1470;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;19.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39816,7078009259;51;22;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000186-creative-ep-630-ohrhorer-schwarz.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Sandisk Sansa Fuze 4 GB;"Sandisk Sansa Fuze MP3-/Video-Player 4 GB mit Radio ";"

Sandisk Sansa Fuze MP3-/Video-Player 4 GB mit Radio

 
 
Mit der verfügbaren Akkuleistung können Sie 24 Stunden lang Musik hören, Bilder anschauen oder spielen.
Der neue Sansa Fuze von SanDisk ist der ideale tragbare Musikplayer für Sie.
Er steht mit einer Speicherkapazität 4 GB in schwarz,rot,pink zur Verfügung.
Sehen Sie sich Ihre Lieblingsvideoclips auf dem 1,9""-Farbdisplay des Sansa Fuze an.
Lauschen Sie dem FM-Radio mit 40 voreingestellten Sendern oder probieren Sie den integrierten Sprachrekorder aus. Mit einer unglaublich starken Akkuleistung in einem 0,3"" schmalen Gerät setzt der Sansa Fuze Zeichen.
";2;False;0;;;Sandisk Sansa Fuze MP3-/Video-Player 4 GB mit Radio;sandisk-sansa-fuze-4-gb;True;True;P-1560;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;89.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39789,5565625;52;8;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000180-sandisk-sansa-fuze-4-gb.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Sandisk Sansa Clip 2 GB schwarz;Sandisk Sansa Clip 2 GB mit integriertem FM-Tuner;"

Sandisk Sansa Clip 2 GB mit integriertem FM-Tuner blau, rot, schwarz, pink

digitaler SanDisk Player für MP3, WMA, Secure WMA und FM Radio
kleines, kompaktes Design, kaum größer als eine Streichholzschachtel
FM-Radio mit 40 Stationsspeicherplätzen
Diktiergerät-Funktion über integriertes Mikrofon
4-zeiliges OLED-Display
Sortierung der Titel nach versch. Kriterien möglich, wie z.B. Künstler, Album, Genre, u.a.
bis zu 15-h-Wiedergabe mittels internem, wiederaufladbaren Akku
inkl. abnehmbarem Trageclip, Ohrhörer, USB 2.0 Kabel, Installations-CD mit Bedienungsanleitung
unterstützt Win 2000 / XP / Vista
 
Lieferumfang:
Player inkl. abnehmbarem Trageclip, Ohrhörer, USB 2.0 Kabel, Installations-CD mit Bedienungsanleitung
";2;False;0;;;"Sandisk Sansa Clip 2 GB mit integriertem FM-Tuner ";sandisk-sansa-clip-2-gb-schwarz;True;True;P-1550;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;49.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39789,5530092593;52;8;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000163-sandisk-sansa-clip-8-gb-schwarz.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Sandisk Sansa Clip 8 GB schwarz;"Sandisk Sansa Clip 8 GB mit integriertem FM-Tuner ";"

Sandisk Sansa Clip 8 GB mit integriertem FM-Tuner schwarz

 
digitaler SanDisk Player für MP3, WMA, Secure WMA und FM Radio
kleines, kompaktes Design, kaum größer als eine Streichholzschachtel
FM-Radio mit 40 Stationsspeicherplätzen
Diktiergerät-Funktion über integriertes Mikrofon
4-zeiliges OLED-Display
Sortierung der Titel nach versch. Kriterien möglich, wie z.B. Künstler, Album, Genre, u.a.
bis zu 15-h-Wiedergabe mittels internem, wiederaufladbaren Akku
inkl. abnehmbarem Trageclip, Ohrhörer, USB 2.0 Kabel, Installations-CD mit Bedienungsanleitung
unterstützt Win 2000 / XP / Vista
 
Lieferumfang:
Player inkl. abnehmbarem Trageclip, Ohrhörer, USB 2.0 Kabel, Installations-CD mit Bedienungsanleitung
";2;False;0;;;"Sandisk Sansa Clip 8 GB mit integriertem FM-Tuner ";sandisk-sansa-clip-8-gb-schwarz;True;True;P-1570;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;69.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39789,5485648148;52;8;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000163-sandisk-sansa-clip-8-gb-schwarz.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Canon PIXMA MP550 Multifunktionsgerät;Canon PIXMA MP550 Multifunktionsgerät;"
Canon PIXMA MP550  Multifunktionsgerät
 
 
3 in 1, Drucken, Kopieren, Scannen
 
 
Der PIXMA MP550 überzeugt als exzellentes Multifunktionssystem für zu Hause mit starkem Preis-Leistungs-Verhältnis.
Er kombiniert Komfort mit Klasse beim Dokumenten- und Fotodruck; hohes Tempo bei Druck, Scan und Kopie sind selbstverständlicher Standard.
 
Drucken, Kopieren und Scannen
Druckgeschwindigkeit: bis zu 9,2/6,0 ISO-Seiten pro Minute (SW/Farbe)
Bis zu 9.600 x 2.400 dpi Auflösung, 1 Picoliter feine Tintentröpfchen; 10 x 15 cm Randlosprint in ca. 39 Sek.
5-Tintensystem
5,0 cm großes TFT-Farbdisplay und Easy-Scroll-Bedienrad
Scanner mit bis zu 2.400 dpi
PictBridge und Speicherkarte
ChromaLife100+
Auto Photo Fix II
";2;False;0;;;Canon PIXMA MP540 Multifunktionsgerät - All in One Drucker - Drucken - Scannen - Kopieren - Faxen;canon-pixma-mp550-multifunktionsgeraet;True;True;P-2200;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;109.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39784,3258333333;"22;2095";25;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000161-canon-pixma-mp550-multifunktionsgerat.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000162-canon-pixma-mp550-multifunktionsgerat.jpg;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;AVM Fritz! WLAN Repeater;AVM Fritz! WLAN Repeater N/G zur Erhöhung der Reichweite von W-LAN Netzen;"
AVM Fritz!WLAN Repeater N/G 

zur Erhöhung der Reichweite von W-LAN Netzen

Erhöht schnell und einfach die Reichweite von WLAN-Netzen
Funktioniert in allen WLAN-Funknetzen: 802.11n Draft 2.0 (300 MBit/s), 802.11g/a (54 MBit/s)
und 802.11b (11 MBit/s)
 
Sichere Funkverbindungen dank WPA2-, WPA- und WEP-Verschlüsselung
Integrierter UKW-Minisender (FM-Transmitter 87,5-108 Mhz)
Perfekt abgestimmt auf WLAN-Produkte der FRITZ!Box-Familie
.
";2;False;0;;;AVM Fritz!WLAN Repeater N/G zur Erhöhung der Reichweite von W-LAN Netzen;avm-fritz-wlan-repeater;True;True;P-2730;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;89.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39775,5815509259;19;34;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000157-avm-fritz-wlan-repeater.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000158-avm-fritz-wlan-repeater.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000159-avm-fritz-wlan-repeater.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Adobe Photoshop Elements 7;Adobe Photoshop Elements 7 deutsch WIN.;"
Adobe Photoshop Elements 7 deutsch WIN

Adobe Photoshop Elements 7 kombiniert Leistungsfähigkeit mit einfacher Bedienung,
sodass Ihnen bei der Bearbeitung von Fotos keine Grenzen gesetzt sind.
Machen Sie aus alltäglichen Motiven eindrucksvolle Kunstwerke. Innovative Werkzeuge und Funktionen ermöglichen es Ihnen zum Beispiel,
unerwünschte Objekte mühelos aus einem Foto zu entfernen, mit einer einzigen Mausbewegung gleichzeitig einen Bildbereich auszuwählen und mit Effekten zu versehen,
Zähne aufzuhellen oder einen Himmel noch intensiver wirken zu lassen. Professionell gestaltete Layouts erleichtern Ihnen die Erstellung von Bildbänden,
Fotoalben und interaktiven Online-Galerien, und dank der durchdachten Verwaltung finden Sie jedes Foto im Handumdrehen.
Die wichtigsten Merkmale:
Intuitive Bearbeitungswerkzeuge zur Gestaltung eindrucksvoller Fotoprojekte
Einfache Erstellung unverwechselbarer Kreationen für Print und Web
Effizientes Suchen und Aufrufen von Fotos
";2;False;0;;;Adobe Photoshop Elements 7;adobe-photoshop-elements-7;True;False;P-3010;;;False;0;False;;False;False;0;False;0;1;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;1;0;True;False;10;0;1;1;False;1;10000;;False;True;False;False;109.5000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39774,9070023148;31;20;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000155-adobe-photoshop-elements-7.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000156-adobe-photoshop-elements-7.jpg;;2;;False;ounce;;;;False;False;False;;;;;False;;;;;; +5;0;True;"NAVIGON 1300 Navigationssystem D-A-CH ";"NAVIGON 1300 Navigationssystem D-A-CH ";"

NAVIGON 1300 Navigationssystem D-A-CH

 
NAVIGON MyRoutes, Clever Parking , POI Klick, Fahrspurassistent Pro, Reality View Light
 
 
NAVIGON 1300 Besonders klein und trotzdem voll mit Features.
Die NAVIGON 13er-Serie kann viel mehr, als Sie vielleicht im ersten Moment denken.
Denn in dem kleinen smarten Gehäuse stecken überaus nützliche Funktionen.
Zum Beispiel NAVIGON MyRoutes, das Ihnen jederzeit genau die Route empfiehlt, die zu Ihnen und Ihrem Fahrstil passt.
Für eine schnelle und sichere Navigation sorgen zudem ein verbesserter Fahrspurassistent Pro, Reality View Light und viele weitere Helfer.
 
NAVIGON MyRoutes
Je nachdem, welcher Fahrertyp Sie sind, empfiehlt Ihnen NAVIGON MyRoutes die beste Route – zugeschnitten auf Ihren persönlichen Fahrstil,
den Wochentag und die Tageszeit. Darüber hinaus zeigt Ihnen Ihr NAVIGON bis zu zwei weitere Routen.
Das schafft Transparenz. Sie entscheiden, ob Sie unserer Empfehlung folgen oder eine der Alternativen wählen.
 
Clever Parking
hilft Ihnen bei der Parkplatzsuche. Kurz vor Ihrem Ziel zeigt Ihnen Clever Parking Parkplätze in der näheren Umgebung an.
In Deutschland werden Sie sogar über Parkgebühren informiert. So vermeiden Sie langes Suchen und sparen dabei Geld.
 
Fahrspurassistent Pro
hilft Ihnen selbst durch den hektischsten Straßenverkehr hindurch.
Vorausschauend und übersichtlich zeigt er Ihnen an, auf welche Fahrspur Sie für Ihren nächsten und übernächsten Abbiegepunkt wechseln müssen.
 
POI-Klick
ermöglicht durch Anklicken die Auswahl eines auf der Karte angezeigten Sonderziels wie zum Beispiel Rastplätze oder Sehenswürdigkeiten.
Inklusive wissenswerter Informationen wie Adresse, Öffnungszeiten und Telefonnummern. Und auf Wunsch können Sie sich direkt dorthin navigieren lassen.
 
Lieferumfang:
PNA  1300 (3,5"" im 4:3 Format) | Kurzanleitung | Kfz-Ladekabel | Halterung | Vorinstalliertes Kartenmaterial | USB-Kabel
";2;False;0;;;;navigon-1300-navigationssystem-d-a-ch;True;True;P-2130;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;149.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39760,6629166667;"68;2095";14;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000154-navigon-1300-navigationssystem-d-a-ch.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Digitus USB2.0 Hub 7-port;Digitus USB2.0 Hub 7-port;

Digitus USB2.0 Hub 7-port

USB 2.0 und USB 1.1 kompatibel 7 x USB A Buchse (USB 1.1 und 2.0 Endgeräte
Maximale Datenübertragungsrate 480 Mbps
Überspannungsschutz an allen Ausgängen
Kompatibel mit PC und MAC
Lieferung inklusive USB Anschlusskabel und Netzteil
;2;False;0;;;Digitus USB2.0 Hub 7-port;digitus-usb20-hub-7-port;True;True;P-0045;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;20.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39757,6835532407;26;;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000153-digitus-usb20-hub-7-port.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Logitech USB Hub 4-Port USB;Logitech USB Hub 4-Port USB;"

Logitech USB Hub 4-Port USB

Lieferumfang: Logitech Premium 4-Port USB Hub for Notebooks,
USB-Kabel, Schnellstartanleitung, Etui, Netzteil
 
Systemvoraussetzungen PC: Windows 2000, Windows XP, Windows Vista:
 
USB-Anschluss Mac: Mac OS X (10.1 oder höher) USB-Anschluss
";2;False;0;;;Logitech USB Hub 4-Port USB;logitech-usb-hub-4-port-usb;True;True;P-0072;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;22.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39757,6788425926;26;11;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000152-logitech-usb-hub-4-port-usb.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;LogiLink USB HUB mit Netzteil;"LogiLink USB 2.0 Hub 7-Port mit Netzteil ";"

LogiLink USB 2.0 Hub 7-Port mit Netzteil

 
Der schnelle Hub von LogiLink unterstützt den modernen USB 2.0-Standard mit bis zu 480 MBit/s
und erweitert Ihren Anschluss um weitere 7 Ports.
";2;False;0;;;LogiLink USB HUB mit Netzteil;logilink-usb-hub-mit-netzteil;True;True;P-0070;;;False;0;False;;False;False;0;False;0;1;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;17.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39757,6744907407;"26;2095";31;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000151-logilink-usb-hub-mit-netzteil.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Artwizz SeeJacket Crystal Hülle für iPod classic ";"Artwizz SeeJacket Crystal Hülle für iPod classic Vers.2009 ";"

Artwizz SeeJacket Crystal Hülle für iPod classic

80, 120 und 160 GB (2009 & 2010 Version)

 Das SeeJacket Crystal besteht aus robustem, transparentem Kunststoff und schuetzt zuverlaessig
vor Stoessen, Erschuetterung und Abnutzung.
Zugriff auf alle Bedienelemente bleibt natuerlich bestehen.
Eine Befestigungsmoeglichkeit fuer ein Umhaengeband ermoeglicht bequemes Tragen um den Hals.
Das optional einsetzbares Silikon-Pad schuetzt das Click Wheel und laesst weiterhin bequemes Bedienen zu.
";2;False;0;;;Artwizz SeeJacket Crystal Hülle für iPod classic;artwizz-seejacket-crystal-huelle-fuer-ipod-classic;True;True;P-1450;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;29.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39754,7778009259;51;30;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000150-artwizz-seejacket-crystal-hulle-fur-ipod-classic.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Artwizz PowerPlug Steckdose;"Artwizz PowerPlug Steckdose auf USB-Ladegerät ";"

Artwizz PowerPlug Steckdose

 
auf USB-Ladegerät für iPods und USB aufladbare MP3-Player Mit diesem USB-Ladegerät kann man den iPod shuffle oder andere MP3 Player,

beziehungsweise andere USB Geräte, einfach an der Steckdose ohne Computer aufladen
(das Gerät besitzt einen Steckdosenstecker und einen USB-Schnittstelle).
In Verbindung mit dem iPod Dock Connector-auf-USB Kabel
kann man alle iPod Modelle an der Steckdose aufladen.

Technische Daten: Europäischer Netzstecker
Eingang: 100-240V AC, 0,15A, 47-63Hz
Ausgang: 5V DC, 1,0A Lieferumfang: Artwizz PowerPlug Steckdose
";2;False;0;;;Artwizz PowerPlug Steckdose;artwizz-powerplug-steckdose;True;True;P-1460;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;17.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39754,709837963;51;30;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000149-artwizz-powerplug-steckdose.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Sennheiser CX 300 Ohrkanalhörer schwarz;"Sennheiser CX 300 Ohrkanalhörer ";"

Sennheiser CX 300 Ohrkanalhörer

Sennheiser CX 300 Ohrhörer, Kraftvoller, bassbetonter Stereo-Sound
Optimaler Sitz im Ohrkanal durch Ohradapter
in unterschiedlichen Größen (im Lieferumfang enthalten)
Sehr gute Abschirmung von Außengeräuschen
Ideal für MP3-, CD-, DVD- und MD-Player
sowie portable Spielekonsolen mit 3,5-mm-Kopfhörerausgang
 
";2;False;0;;;;sennheiser-cx-300-ohrkanalhoerer-schwarz;True;True;P-1490;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;29.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39754,705462963;51;29;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000148-sennheiser-cx-300-ohrkanalhorer-schwarz.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Gear4 IceBox transparent;Gear4 IceBox für iPod nano 4G, transparent;"
Gear4 IceBox für iPod nano 4G, transparent
 
 
Gear4 IceBox für iPod nano 4G, transparent
Transparente Hülle für iPod nano 4G
";2;False;0;;;Gear4 IceBox transparent;gear4-icebox-transparent;True;True;P-1480;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;24.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39754,6834143519;"51;2095";28;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000147-gear4-icebox-transparent.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Apple iPod Touch 16 GB schwarz;"Apple iPod Touch 16GB schwarz ";"
Apple iPod Touch 32 GB schwarz mit integrierter WiFi Funktion

Der iPod touch kann alles, was du am iPod toll findest. Und noch vielmehr. Schlankes neues Design. Mit seinem fantastisch flachen Edelstahl-Design liegt der iPod touch mit dem 3.5 Zoll Touch-Display jetzt noch besser in der Hand. Mobil im Spiel. Durch revolutionäre Technologien wie das Multi-Touch-Display, der Beschleunigungssensor und 3D-Grafiken macht das Spielen auf dem iPod touch besonders viel Spaß. Schlaue Musik Mit der neuen Funktion ""Genius"" wird der iPod touch zu Deinem superintelligenten, persönlichen DJ.
Nur ein paar Fingertipps, und Genius erzeugt eine Wiedergabeliste mit Songs Deiner Mediathek, die gut zusammenpassen. Internet überall Internetzugang überall, wo ein drahtloses Netzwerk zur Verfügung steht, damit Sie immer mit dabei sind. Multitouch-Oberfläche: Die revolutionäre Technologie des iPhone und die Software Version 3.1 stecken in diesem genialen iPod. Das brillante Breitformat-Display rückt Ihre Videos und Spiele ins beste Licht und dank OpenGL sehen die Spiele jetzt noch besser aus Surfen Sie mit Safari im Web und sehen Sie YouTube Videos auf dem iPod mit integrierter Wi-Fi Funktionalität an. Mit Ihrem iPod touch können Sie im iTunes Wi-Fi Music Store nach Songs suchen, Hörproben abspielen und Titel kaufen.
Lieferumfang: iPod touch, Ohrhörer, USB 2.0 Kabel, Kurzanleitung
 
Schlankes neues Design
Mit seinem fantastisch flachen Edelstahl-Design liegt der iPod touch so gut in der Hand wie nie zuvor. Ebenfalls Eindruck machen der neue Lautstärkeregler und der integrierte Lautsprecher.

Spiele
Speziell auf die iPod touch Technologie zugeschnittene Spiele sind nur noch einen Fingertipp entfernt. Stöbere in hunderten von Spielen im App Store direkt auf Deinem iPod touch, und wenn Du gefunden hast, was Du suchst, kannst Du es einfach laden und dann kann es losgehen.
 
Steuerung per Fingertipp
Viele Spiele auf dem iPod touch nutzen die Multi-Touch-Technologie für besonders exakte Fingertipp-Steuerung der verschiedenen Spielelemente. Beim Schach ziehst Du mit dem Finger die Figuren, bei Würfelspielen bewegst Du die Würfel. Durch Ziehen mit zwei Fingern kannst Du die Anzeige vergrößern und verkleinern, Deine Figur nach links oder rechts drehen, und durch einfaches Antippen triffst Du eine Auswahl.
 
Musik
Blättere in den Albumcovern Deiner Musiksammlung. Erstelle immer wieder neue Genius Wiedergabelisten und erweitere Deine Sammlung aus dem iTunes Wi-Fi Music Store überall, wo ein Wi-Fi-Hotspot in der Nähe ist.
Mit Cover Flow lebt das Flair einer CD- oder Plattensammlung wieder auf. Wer erinnerst sich nicht an das Gefühl beim Durchblättern der Sammlung? Das gibt es jetzt auch auf dem iPod touch: einfach iPod drehen, durch die Cover blättern, ein Album auswählen, fertig. Ein Fingertipp aufs Cover, und schon siehst Du die Titelliste, ein weiterer Tipp spielt die Musik ab, und dabei kannst Du sogar die Songtexte anzeigen.
 
Ein Musikgenie
Stell Dir vor, Du hörst einen Song. Toll wären jetzt andere Titel, die gut dazu passen. Was machst du? Ganz einfach: Du verwendest die neue Funktion ""Genius"". Diese findet die Songs in Deiner Mediathek, die gut zusammenpassen. Du erhältst eine Genius Wiedergabeliste, die Du sofort anhören, sichern oder sogar aktualisieren kannst. Verlass Dich also auf den Genius von iTunes, wenn Du einen Mix willst, auf den Du selbst nicht gekommen wärst.
 
Lautsprecher integriert
Mit dem integrierten Lautsprecher kannst Du Musik und Gespräche ohne Kopfhörer hören – perfekt für zwangloses Hörvergnügen.

Längere Batterielaufzeit
Jetzt kannst Du noch länger rocken (und ansehen und spielen). Der iPod touch hält bis zu 36 Stunden bei Musik oder bis zu 6 Stunden bei Videos durch. Das reicht für drei oder vier Filme zwischen den Ladevorgängen.
 
Internet
Surfe im Internet mit Wi-Fi. Du kannst detailgenaue HTML-E-Mails mit Anlagen empfangen und Wegbeschreibungen und aktuelle Verkehrsinformationen abrufen. Auch als YouTube-Fan entgeht Dir nichts.
 
Überall ins Internet
Der iPod touch ist der einzige iPod mit kabellosem 802.11b/g Internetzugriff. Bei bestehender Wi-Fi-Verbindung kannst Du im Internet surfen und Nachrichten lesen, Sportergebnisse sehen, Rechnungen bezahlen und online einkaufen.
 
Wer suchet, der findet
Der iPod touch synchronisiert Deine Lesezeichen vom PC oder Mac, sodass Du ruck zuck auf Deine Lieblingsseiten zugreifen kannst. Die Google- und Yahoo!-Suche ist schon integriert, sodass Du im Web schnell findest, was Du suchst.
 
Zoom mit Aussicht
Jeden beliebigen Ausschnitt einer Webseite kannst Du vergrößern, indem Du mit dem Finger darauf tippst oder mit zwei Fingern die Anzeige aufziehst. Websites lassen sich im Hoch- oder Querformat anzeigen: einfach den iPod touch um 90 Grad drehen, und schon wird auch die Darstellung der Website gedreht.
 
Eigene Weblinks
Für häufig besuchte Websites, etwa die einer Zeitung, eines Blogs oder eine Sport-Website, kannst Du einfach ein Symbol auf dem Home-Bildschirm erstellen. Deine Lieblingsseiten sind über mit Safari erstellte Weblinks nur einen Fingertipp entfernt.
 
Rock 'n' Run mit Nike+
Im iPod touch ist kabellose Unterstützung für Nike + iPod integriert. Du brauchst nur einen Nike + iPod Sensor in Deinem Schuh, und schon kann's losgehen.
 
Das optimale Lauftraining
Im iPod touch ist jetzt Unterstützung für Nike + iPod integriert. Einfach den Nike + iPod Sensor (separat erhältlich) in den Nike+ Laufschuh einsetzen, und es kann losgehen. Der Sensor überträgt die Laufdaten drahtlos an den iPod touch – er erfasst die gelaufene Zeit, die zurückgelegte Strecke und die verbrauchten Kalorien. Außerdem gibt er Dir gesprochenes Feedback zu Deinen Trainingsfortschritten.
 
Das optimale Fitnesstraining
Diese Funktion kann auch zusammen mit neuen, in vielen Fitnessstudios vorhandenen Geräten für das Ausdauertraining gekoppelt werden. Suche einfach nach mit Nike + iPod kompatiblen Laufbändern, Elliptical Trainern, Steppern und Hometrainern.
";2;False;0;;;Apple iPod Touch 16 GB;apple-ipod-touch-16-gb-schwarz;True;True;P-1250;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;229.9000;229.9000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39754,6690972222;43;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000141-apple-ipod-touch-16-gb-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000142-apple-ipod-touch-16-gb-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000143-apple-ipod-touch-16-gb-schwarz.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Hannspree HL231DPB 58,4 cm (23 Zoll);Hannspree HL231DPB 58,4 cm (23 Zoll) Widescreen LCD Monitor DVI, VGA (Kontrast dyn. 1000:1, 5ms Reaktionszeit) schwarz;Marke: HANNSPREE
Farbe: schwarz (hochglanz)
Produkthöhe: 18.8 cm
Produktbreite: 54.6 cm
Bildschirm Größe: 23 inches
Bildschirm Auflösung: 1920x1080 Pixel
Max. Bildschirmauflösung: 1920 x 1080 pixels
Weitere Spezifikationen
Leistung: 27 Watt
;2;False;0;;;Hannspree HL231DPB 58,4 cm (23 Zoll);hannspree-hl231dpb-584-cm-23-zoll;True;True;P-2540;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;149.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39741,7897800926;"12;2095";26;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000137-hannspree-hl231dpb-584-cm-23-zoll.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000138-hannspree-hl231dpb-584-cm-23-zoll.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000139-hannspree-hl231dpb-584-cm-23-zoll.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Canon PIXMA MP270 Multifunktionsgerät;"Canon PIXMA MP270 Multifunktionsgerät ";"
Canon PIXMA MP270 Multifunktionsgerät
 
 
3 in 1, Drucken, Kopieren, Scannen
 
 
Der PIXMA MP270 ist ein kompaktes, günstiges Multifunktionssystem.
Seine Stärken sind der schnelle Dokumentendruck und der Fotodirektdruck in Laborqualität von PictBridge-kompatiblen Kameras und Fotohandys.
 
Drucken, Kopieren und Scannen
Druckgeschwindigkeit: bis zu 8,4/4,8 ISO-Seiten pro Minute (SW/Farbe)
Bis zu 4.800 dpi Auflösung und 2 Picoliter feine Tintentröpfchen
10 x 15 cm Randlosprint in ca. 45 Sek.
Easy-WebPrint EX
Scanner mit bis zu 1.200 dpi und Auto-Scan-Modus
PictBridge
Selbst öffnendes Papierausgabefach
ChromaLife100+
";2;False;0;;;Canon Pixma MX310 - All in One Drucker - Drucken - Scannen - Kopieren - Faxen;canon-pixma-mp270-multifunktionsgeraet;True;True;P-2210;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;89.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39741,6931365741;22;25;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000132-canon-pixma-mp270-multifunktionsgerat.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"TomTom XL Black Edition Europe Traffic ";"TomTom XL Black Edition Europe Traffic ";"

TomTom XL Black Edition Europe Traffic

TMC ,4,3"" Display, 42 Länderkarten

 
TomTom Navigationsgerät XL Classic Black Edition mit 4,3 Zoll Farb-Touchscreen,
RDS/TMC, 42 vorinstallierten Karten europäischer Länder sowie vielen Innovationen für eine verbesserte und komfortable Navigation
TMC-Empfänger für einen einfachen Zugriff auf Verkehrsinformationen und verschiedene Routenoptionen für die schnellste oder kürzeste Strecke
Mit TomTom HOME und TomTom Map Share das Navi auf dem neusten Stand halten und weitere Features am PC/Mac nutzen
TomTom XL Classic Black Edition in einem edlen schwarzen Gehäuse mit passender EasyPort Halterung für eine einfache Frontscheibenmontage
 
Lieferumfang:
TomTom XL Classic Black Edition, EasyPort-Halterung, USB-Kabel, Autoladegerät, Dokumentation, RDS/TMC-Verkehrsinfo-Empfänger
";2;False;0;;;;tomtom-xl-black-edition-europe-traffic;True;True;P-2000;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;182.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39724,7946643519;66;4;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000131-tomtom-xl-black-edition-europe-traffic.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Western Digital My Passport 320 GB;"Western Digital BAAA3200ABK My Passport Essential 320GB ";"

Western Digital BAAA3200ABK My Passport Essential 320GB  

 
Schnittstellen:1 x Hi-Speed USB, Schnittstellen Typ:Hi-Speed USB, Kapazität:320 GB, Merkmale:
Kennwortauthentifizierung, Details zu Service & Support
Übertragungsrate Schnittstelle:480 Mbit/s, Software inbegriffen:Smartware,
Erforderliches Betriebssystem:Microsoft Windows XP, Microsoft Windows 7, Apple MacOS X 10.4,
Microsoft Windows Vista, Apple MacOS X 10.6, Apple MacOS X 10.5, Stromversorgung:USB-Bus,.
Enthaltene Kabel:1 x USB-Kabel - extern
";2;False;0;;;"Western Digital My Passport 320 GB externe Festplatte ";western-digital-my-passport-320-gb;True;True;P-2590;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;99.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39724,7845023148;14;21;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000130-western-digital-my-passport-320-gb.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Trekstor DataStation maxi g.u 1TB ";"Trekstor DataStation maxi g.u externe Festplatte 1TB ";"

Trekstor DataStation maxi g.u Externe Festplatte 1 TB

 
USB 2.0 inkl. Nero BackItUp 2 Essentials
 
 
Optimale Speicherplatzerweiterung
Die DataStation maxi g.u ist die perfekte Lösung für das
tägliche Backup oder die Speicherplatzerweiterung Ihres PCs.
Die externe 3,5“ Festplatte bietet ausreichend Platz
zum Speichern und Archivieren der heimischen Musik-
und Videosammlung, digitaler Fotos oder anderer Dateien. 
 Schnell und bedienungsfreundlich
Mit dem Hi-Speed USB 2.0 Anschluss bietet die
DataStation maxi g.u einen schnellen Datentransfer.
Die Festplatte ist zudem bereits vorformatiert und
ohne Treiber sofort betriebsbereit.
Unterstützt werden alle gängigen
Dateisysteme von Windows®, Linux® und Mac® OS X,
sowie die Betriebssysteme Microsoft
Windows® 2000 / XP/ Vista, Mac® OS X ab 10.3 und Linux® ab Kernel 2.6.x.
Die Festplatte wird über das mitgelieferte Netzteil mit Strom versorgt. 
Der Ein-/Ausschalter am Festplattengehäuse verhindert überflüssigen Stromverbrauch. 
Exklusives Aluminiumgehäuse
Das exklusive Aluminiumgehäuse der DataStation maxi g.u
sorgt für die optimale Kühlung der Festplatte,
so kommt die externe Festplatte
ohne Lüfter aus und ist leise während des Betriebs 
Inklusive Nero Software „BackItUp2 Essentials“
Die ebenfalls im Lieferumfang enthaltene
Nero Software rundet das Bild der mobilen, externen Festplatte perfekt ab.
Mit Nero BackItUp2 Essentials können Sie Backups Ihrer Daten sehr einfach planen.
So können einzelne Dateien oder ganze Laufwerke gesichert werden.
Um die Datenmenge gering zu halten, komprimiert die Software die Backups direkt „on the fly“.
Auf Wunsch lassen sich die gesicherten Daten auch per Passwortschutz vor unbefugtem Zugriff schützen.
";2;False;0;;;"Trekstor DataStation maxi g.u-externe Festplatte 1 TB ";trekstor-datastation-maxi-gu-1tb;True;True;P-2620;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;129.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39720,7329166667;15;2;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000129-trekstor-datastation-maxi-gu-1tb.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Western Digital My Passport 250 GB ";Western Digital My Passport Essential 250GB;"

Western Digital My Passport Essential 250GB Schwarz

 
Mobiler Hochleistungsspeicher für Ihren Mac® oder PC.
Es ist leicht und robust, einfach zu transportieren und erfordert kein externes Netzteil.
Im Lieferumfang sind eine Software zur Synchronisierung und Verschlüsselung sowie
Google™-Software enthalten.
USB-gesteuert Software zur Synchronisation und Verschlüsselung
Besonders gut tragbare Form
Zum Transportieren von wichtigen Dateien und E-Mails zwischen Büro und Wohnung sowie unterwegs
Gemeinsame Nutzung von großen Dateien zwischen Büro und Wohnung, zwischen PC und Mac.
Kapazität: 250 GB (GigaByte)
maximale Transferrate: 480 Mb/s über USB 2.0
USB 2.0 Anschluss
für PC oder Macintosh Computer
 
Lieferumfang:
Tragbares Festplattenlaufwerk, USB 2.0-Kabel, Schnellinstallationsanleitung
";2;False;0;;;Western Digital My Passport 250 GB 2,5 Zoll Schwarz;western-digital-my-passport-250-gb;True;True;P-2580;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;89.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39707,7523263889;14;21;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000128-western-digital-my-passport-250-gb.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"NAVIGON 4310 max Navigationssystem Europa ";"NAVIGON 4310max Navigationssystem Europa ";"

NAVIGON 4310max Navigationssystem Europa

 
 
40 Länder, inklusive TMC, NAVIGON MyRoutes
 
 
NAVIGON 4310 max Ist nicht nur schön,sondern auch intelligent.
Egal, wo es gerade langgeht, jetzt haben Sie immer eine gute Aussicht: auf die NAVIGON 43 max Serie mit ihrem edlen Design.
Doch die Routenplaner glänzen auch durch innere Werte.
Zum Beispiel empfiehlt Ihnen NAVIGON MyRoutes jederzeit die beste Strecke, zugeschnitten auf Ihren persönlichen Fahrstil, den Wochentag und die Tageszeit.
Für weiteren Komfort sorgen Features wie Reality View Pro, Clever Parking und die TMC-Routeninfo.
 
NAVIGON MyRoutes
Je nachdem, welcher Fahrertyp Sie sind, empfiehlt Ihnen NAVIGON MyRoutes die beste Route – zugeschnitten auf Ihren persönlichen Fahrstil, den Wochentag und die Tageszeit.
Darüber hinaus zeigt Ihnen Ihr NAVIGON bis zu zwei weitere Routen. Das schafft Transparenz. Sie entscheiden, ob Sie unserer Empfehlung folgen oder eine der Alternativen wählen.
 
TMC-Routeninfo
zeigt ihnen im Fall einer Staumeldung eine Alternativroute mit aktualisierter Entfernung und Ankunftszeit.
Sie entscheiden, ob eine Umfahrung in Ihrem Fall sinnvoll ist oder ob Sie die ursprüngliche Route beibehalten wollen.
 
Reality View Pro
zeigt Straßen nicht als Linien, sondern realistisch aus Asphalt und mit Mittelstreifen. So behalten Sie an Autobahnkreuzen und Ausfahrten leichter den Überblick.
 
Clever Parking
hilft Ihnen bei der Parkplatzsuche. Kurz vor Ihrem Ziel zeigt Ihnen Clever Parking Parkplätze in der näheren Umgebung an.
In Deutschland werden Sie sogar über Parkgebühren informiert. So vermeiden Sie langes Suchen und sparen dabei Geld.
 
Lieferumfang:
PNA 4310 max (4,3"" im 16:9 Format) | Kurzanleitung | Halterung Kfz-Ladekabel mit integrierter TMC-Antenne |Vorinstalliertes Kartenmaterial für 40 Länder | USB-Kabel
";2;False;0;;;;navigon-4310-max-navigationssystem-europa;True;True;P-2120;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;199.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39661,6380787037;68;14;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000127-navigon-4310-max-navigationssystem-europa.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Logitech G5 Laser Mouse refresh;"Logitech G5 Laser Mouse refresh ";"
Logitech G5 Laser Mouse refresh
 
 
Kabelgebundene 7-Tasten Tuningmaus mit Laser-Engine
 
 
Spieletaugliche Laser Engine mit 2000 dpi
1.000 Meldungen/Sekunde ermöglichen Präzision bei jeder Geschwindigkeit
Gewichtstuning mit bis zu 38 Gramm
Die Oberfläche mit DryGrip-Technologie beugt müden, verschwitzten Händen vor
Füße aus Polytetrafluorethylen bieten eine besonders gute Gleitfähigkeit der Maus
";2;False;0;;;Logitech G5 Laser Mouse Neu;logitech-g5-laser-mouse-refresh;True;True;P-2770;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;59.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39656,6560300926;21;11;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000124-logitech-g5-laser-mouse-refresh.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Microsoft Bluetooth Mouse 5000 ";"Microsoft Bluetooth Notebook Mouse 5000 ";"
Microsoft Bluetooth Notebook Mouse 5000
 
Bluetooth- und Lasertechnik in Microsoft-Qualität 
 
Mehr Komfort und Sicherheit mit modernen Bluetooth-Notebooks:
Das lästige Empfängermodul für die USB-Schnittstelle entfällt,
die Maus nimmt direkt Kontakt auf mit dem fest eingebauten Bluetooth-Empfänger des Notebooks
Stets informiert: Batteriestandsanzeige auf der Oberseite des Gehäuses (Grün/Rot für Batteriestand OK und niedrig)
Geringe Abmessungen und niedriges Gewicht machen die Maus zum idealen Reisebegleiter.
Bei Nichtverwendung wird die Maus sicher im formschönen Transportcase aufbewahrt
Für Rechts- und Linkshänder geeignetes Gehäuse mit 4 leichtgängigen Maustasten inklusive Scrollrad
Microsoft High Defi nition Laser Technologie für maximale Präzision auch Unterwegs
";2;False;0;;;Microsoft Bluetooth Notebook Mouse 5000;microsoft-bluetooth-mouse-5000;True;True;P-2780;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;49.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39656,6470949074;"21;2095";3;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000123-microsoft-bluetooth-mouse-5000.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Apple iPod shuffle 2 GB pink;Apple iPod shuffle 2 GB pink;"

Apple iPod shuffle 2GB pink
 

 
Wie seine größeren Geschwister besitzt auch der iPod shuffle kreisförmig
angeordnete, ergonomische Bedienelemente.
Der Kopfhöreranschluss am iPod shuffle dient gleichzeitig als Dock-Anschluss.
Drehen Sie den iPod shuffle auf die Seite und setzen Sie ihn in das mitgelieferte Dock ein.
Dank eines stabilen, integrierten Clips lässt sich der iPod shuffle fast überall befestigen.
Klemmen Sie ihn am T-Shirt, am Hemdkragen oder am Trageriemen von Rucksack oder Handtasche fest.
Lassen Sie sich aufs Ungewisse ein: Verwenden Sie den Schalter für die Zufallswiedergabe,
um den Inhalt Ihres iPod shuffle neu zu mischen.
verbesserte Kopfhörer und das neue iTunes 8.0
 
Einfach Musik anhaben mit dem Apple iPOD SHUFFLE 2GB.Tragen Sie bis zu 500 Songs am Ärmel. Oder am Gürtel. Oder am Sportoutfit. Das Erkennungszeichen für Musikfans - den Apple iPOD SHUFFLE. Füllen Sie Ihren Apple iPOD SHUFFLE silber 1GB spielend einfach. iTunes ist der Store für Unterhaltungsinhalte. Ihre super organisierte Musiksammlung und Jukebox. Und die Software, mit der Sie Ihren Apple iPOD SHUFFLE mit einem Mausklick füllen. Das farbige Gehäuse aus eloxiertem Aluminium in silber passt zum genial einfachen Design des Apple iPOD SHUFFLE.
 
Leistungseigenschaften
 
2 GB Flash-Memory Speicher
min. Audio-Datenrate: 8 KBit/s
max. Audio-Datenrate: 320 KBit/s
Frequenzgang-Untergrenze: 20 Hz
Frequenzgang-Obergrenze: 20000 Hz
 
Formate/Standards
 
MP3-Standard
AAC + MP3 Standard
WAV-Dateiformat kompatibel
Audible-Format kompatibel
AIFF-Format kompatibel
 
Bedienung
 
Musiktitel-Verwaltung
 
Leistungsaufnahme/Spannungsversorgung

Li-Polymer Akku
12 Std. Spieldauer mit Akku
Ladezeit für Akku: 4 Std.
 
Anschlüsse
 
Kopfhörer-Anschluß
USB-Schnittstelle
Anschluß für Docking-Station
 
Gehäuse-Eigenschaften
 
Breite: 4.12 cm
Höhe: 2.73 cm
Tiefe: 1.05 cm
Gewicht: 15.5 g

 
";2;False;0;;;Apple iPod shuffle 2 GB pink;apple-ipod-shuffle-2-gb-pink;True;True;P-1130;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;64.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39650,6338888889;37;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000118-apple-ipod-shuffle-2-gb-pink.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000119-apple-ipod-shuffle-2-gb-pink.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000120-apple-ipod-shuffle-2-gb-pink.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Me2 ME600HD 500 GB Multimediafestplatte ";"Me2 ME600HD Multimediafestplatte 500 GB ";"

Me2 ME600HD Multimediafestplatte 500 GB

 
 
3,5 Zoll USB 2.0 / Scart / HDMI Multimedia
 
 
Komplett-Lösung für Film- & TV-in Top-Qualität
Direkter Anschluss an das Fernsehgerät zur sofortigen
Wiedergabe von Filmen, Musik oder Fotos -
kein Computer erforderlich 
Mit der Fernbedienung durch die Medien navigieren
Das Bild kann bis zu HDTV-Auflösungen von 1080i skaliert werden -
HDMI, Scart, Component-Video und Digital-Audio Anschlüsse -
Externe USB 2.0 Multimedia Festplatte - Kapazitäten: bis 1000 GB -
High-speed USB 2.0 Externe USB 2.0 Multimedia Festplatte -
Aluminium Gehäuse - Stand-alone Media Player zur Wiedergabe
von MPEG-1, MPEG-2, DivX/Xvid, JPEG, GMC, Qpel, MP3 (ID3 tag),
WAW Media Daten - direkte Wiedergabe von DVD Ordnern - Orderner-Navigation - 
Eigene Playlist benutzen und bearbeiten - einfache Dateiführung, intuitive Bedienung -
unterstützt Progressive Scan (NTSC-480p, PAL-576p)
unterstützt NTFS und FAT32 Dateisysteme geeignet für HDTV (skaliert auf 1080i)
 
Lieferumfang: TV-Infrarotfernbedienung Hi-Speed USB 2.0-Kabel, HDMI-Anschluss
A/V-Kombikabel Component-Kabel Software-CD Bedienungsanleitung
AC Netzteil (100-240V) + Netzkabel
";2;False;0;Me2 ME600HD 500 GB Multimediafestplatte;Me2 ME600HD 500 GB Multimediafestplatte;"Me2 ME600HD 500 GB Multimediafestplatte ";me2-me600hd-500-gb-multimediafestplatte;True;True;P-2660;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;129.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39650,625474537;"16;2095";;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000117-me2-me600hd-500-gb-multimediafestplatte.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Samsung P2450H 24 Zoll HD LCD-Monitor;Samsung P2450H 24 Zoll HD LCD schwarz;"

Samsung P2450H 24 Zoll HD LCD schwarz


HDMI ,Kontrastverhältnis 70000:1, Reaktionszeit 2ms
 

 
Das Modell überzeugt neben dem eleganten ""Touch of Color"" Design auch durch die technischen Features: Neben der VGA- und DVI-D-Schnittstelle bietet das Display auch einen HDMI-Anschluss.
Das sehr hohe dynamische Kontrastverhältnis von 70.000:1 und die Reaktionszeit von 2 ms (G/G) machen den SyncMaster P2450H ebenfalls für Gamer interessant.
Hochwertiges 24"" Display mit Full HD Auflösung und HDMI
Kontrast (dynamisch): 70000:1
Reaktionszeit: 2 ms (G/G)
Lieferumfang: Monitor, Signalkabel, Netzkabel, Treiber CD, Handbuch (CD)
";2;False;0;;;;samsung-p2450h-24-zoll-hd-lcd-monitor;True;True;P-2460;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;249.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39650,5278472222;9;5;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000114-samsung-p2450h-24-zoll-hd-lcd-monitor.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000115-samsung-p2450h-24-zoll-hd-lcd-monitor.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000116-samsung-p2450h-24-zoll-hd-lcd-monitor.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;Microsoft Windows Vista Home Premium OEM 32 Bit;Microsoft Windows Vista Home Premium OEM 32Bit;"
Mit Windows Vista erledigen Nutzer sicherer und einfacher ihre täglichen Aufgaben und finden sofort, was sie benötigen. Es bietet neue Möglichkeiten für die digitale Unterhaltung und einfachere Kommunikationswege mit anderen Menschen, sowohl zu Hause als auch unterwegs.
Sicherheit und Bedienkomfort standen im Zentrum der Entwicklung von Windows Vista. Nutzer können sich auf die neu gestaltete Bedienoberfläche freuen – im neuen Look and Feel. Außerdem kümmert sich Vista noch mehr darum, Ordnung in die Datenflut auf der Festplatte zu bringen. Es wird leichter, Dokumente zu finden oder Multimedia-Daten zu verwalten und zu nutzen.
 
Neue Benutzeroberfläche
Windows Vista vereinfacht deutlich das Arbeiten mit dem PC. So sorgt eine benutzerfreundliche Oberfläche dafür, dass der Anwender jederzeit sofort auf die gewünschten Daten zugreifen kann. Integrierte, systemweite Suchfunktionen vereinfachen das Speichern, Auffinden, Verwalten und Organisieren wichtiger Dateien und Programme.
 
Damit bleiben E-Mails, Dokumente, Bilder, Videos, Musik, Spiele und Websites immer im Griff. Bei der Suche auf dem Desktop-PC braucht der Nutzer nicht mehr den Namen einer Datei zu kennen, es reicht ein Wort im Dokument, der Musikinterpret oder das Datum der Fotografie, um sie zu finden.
 
 
Das neue Vista Start-Menü mit integrierter Schnellsuche 
 
Mit „Flip“ lässt sich von einem geöffneten Fenster komfortabel zum nächsten wechseln, wobei für jedes Fenster eine Live-Miniaturansicht angezeigt wird. Mit Hilfe der Miniaturansichten kann der Nutzer das gewünschte Fenster schnell ermitteln, insbesondere wenn mehrere Fenster desselben Typs geöffnet sind. „Flip 3D“ ermöglicht das Verwenden des Bildlaufrads der Maus zum Sichten mehrerer geöffneter Fenster und anschließenden Auswählen des gewünschten Fensters.
 
Damit Informationen nur einen Mausklick entfernt sind, bietet Windows Vista Minianwendungen. Diese verbinden sich mit Web Services zur Wiedergabe von ständig aktualisierten Informationsdiensten wie Wetterberichte, Nachrichten oder Internet-Radio-Programme. Sie können auch alle Instant-Messaging-Kontakte und Tagesaufgaben anzeigen sowie als Taschenrechner oder Notizzettel fungieren. Alle Minianwendungen werden über die am rechten Bildschirmrand befindliche Windows Sidebar organisiert und aufgerufen.
 
Windows Aero
Windows Vista ist das erste Windows-Betriebssystem mit einer Benutzerumgebung, die mühelos an die Hardwaremöglichkeiten des Computers angepasst werden kann, auf dem sie installiert ist. Auf allen Computern, welche die Mindestanforderungen an die Hardware erfüllen, wird die Basisbenutzerumgebung von Windows Vista angezeigt, in der Sie die bereits erwähnten optimierten Oberflächenfunktionen finden.
 
Windows Aero ist eine Umgebung mit einem zusätzlichen Grad an visueller Ausgereiftheit, die reaktionsschneller und verwaltbarer ist und Windows-Benutzern mehr Übersichtlichkeit und Benutzerfreundlichkeit bietet.
 
 
Windows Vista Aero bietet spektakuläre visuelle Effekte, wie zum Beispiel transparente Bedienelemente 
 
Jederzeit verbunden
Windows Vista-basierte Heimcomputer, Laptops oder Tablet-PCs sind nach dem Einschalten so schnell einsatzbereit wie herkömmliche Elektronikgeräte und lassen sich auch genauso schnell ausschalten. Damit können Privatnutzer sofort auf ihre Anwendungen zugreifen, im Internet surfen oder mit ihren Freunden und Bekannten kommunizieren.
 
Mit dem neuen „Ruhezustand“ von Windows Vista dauert trotz niedrigen Stromverbrauchs die Reaktivierung des PCs nur zwei bis drei Sekunden. Dadurch braucht der Anwender seinen Computer weniger häufig herunterfahren und neu starten. Außerdem passt das Betriebssystem seine Leistung automatisch an verschiedene Nutzer an, indem es die jeweils am häufigsten genutzten Anwendungen bereits vor dem Aufruf lädt.
 
 
Die Windows Sidebar bietet schnellen Zugriff auf Minianwendungen, wie etwa Wetterberichte oder Nachrichten 
 
Über das Windows Synchronisierungscenter gleicht er die Inhalte tragbarer Geräte wie Telefone, PDAs und Musik-Player mit PCs ab. Über das Windows Mobilitätscenter kann er sogar auf Einstellungen mobiler Computer zugreifen und diese ändern.
 
Plattform für Digitale Unterhaltung
Windows Vista enthält ein Media Center mit Zugriff per Fernbedienung auf alle wichtigen Unterhaltungsmöglichkeiten wie Musik, Bilder, Filme, TV, aufgezeichnete Sendungen und Services. Da die Software HD TV und HD DVD unterstützt, wurde die Oberfläche für High-Definiton (HD) Breitwand-Bildschirme optimiert und überarbeitet. Sie bietet eine einfache und übersichtliche Suche nach allen digitalen Medien. Das Media Center lässt sich über die Media Center Extender-Funktionalität der Xbox 360 auf das gesamte Heim erweitern.
 
Microsoft treibt gemeinsam mit Intel und AMD die weitere Entwicklung des digitalen Heims voran. Die Intel Viiv-Technologie bietet eine neue Plattform für digitale Unterhaltung, die leistungsstarke Dual-Core-Prozessoren nutzt. AMD bietet AMD Live! auf Multimedia-Desktop-PCs und -Notebooks an, die rechtzeitig zum Erscheinen von Windows Vista auf den Markt kommen.
 
 
Mit Flip und Flip 3D navigiert man dank übersichtlicher Miniaturansichten mühelos durch die geöffneten Fenster 
 
Musik, Bilder und Spiele
Der in Windows Vista integrierte Media Player 11 enthält eine aufgefrischte Oberfläche mit neuen Navigationsmöglichkeiten. Damit durchsuchen Musikfans noch schneller und effizienter ihre Sammlungen: Während der Eingabe zeigt der Media Player 11 sofort eine aktualisierte Auswahl möglicher Begriffe an.
 
Mit der Windows Fotogalerie können Nutzer ihre Fotos und Videos von Digitalkameras miteinander tauschen und ansehen. Sie vereinfacht die Verwaltung von Bildern und enthält grundlegende Schneide- und Korrekturfunktionen. Für das Importieren, Schneiden und Organisieren von Videos steht der Windows Movie Maker zur Verfügung.
 
Die persönlichen Lieblingsspiele lassen sich über den Games Explorer einfacher aufrufen. Die aktuelle Version der Programmier-Schnittstelle DirectX 10 bietet größeren Detailreichtum und mehr Tiefenschärfe bei Spielegrafiken sowie eine fünffach höhere Leistungsfähigkeit. Außerdem stehen viele neue und überarbeitete Games zur Verfügung wie „Halo 2 für Windows Vista“, „Flight Simulator X“ und „Mahjong-Giganten“.
 
 
Über das Windows Media Center lassen sich Fernsehprogramme, Filme, Musik und Bilder bequem per Fernbedienung steuern 
 
Sicherheit und Jugendschutz
Das neue Sicherheitskonzept von Windows Vista hat zu zahlreichen Innovationen geführt. So schützt der Windows Defender den PC vor aktuellen Gefahren wie Würmer, Viren und Spyware. Der integrierte Internet Explorer 7 verhindert unter anderem Schäden durch gefälschte Websites und E-Mails.
 
Der neue Benutzerkontoschutz unterscheidet Standardaktivitäten von besonders kritischen Aktionen. Standardaktivitäten wie das Surfen im Web, das Senden von E-Mails oder das Verwenden von Office-Programmen sind wenig sicherheitskritisch und erfordern daher keine besonderen Berechtigungen. Wenn der Anwender jedoch eine kritische Aktion durchführen will, zum Beispiel die Installation eines neuen Programms, fordert Windows Vista die Eingabe eines eigenen Kennworts. Dadurch wird es für bösartige Programme schwieriger, den PC zu befallen.
 
Außerdem verhindert der Benutzerkontoschutz, dass PC-unerfahrene Familienmitglieder unbeabsichtigt sicherheitskritische Aktionen durchführen oder heruntergeladene Programme installieren. Mit speziellen Sicherheitseinstellungen in Windows Vista können Eltern zudem die Computernutzung ihrer Kinder kontrollieren.
 
Komfortabler Surfen
Internet Explorer 7 bietet nicht nur wichtige neue Sicherheits- und Datenschutzfeatures, sondern erleichtert auch gängige Aufgaben durch Features wie Registernavigation (Anzeige von Fenstern im Registerkartenformat), Onlinesuche und an die Blattgröße angepasste Druckvorgänge.
 
Gleichzeitig werden neue Tools bereitgestellt, um einen direkten Zugriff auf die gewünschten Informationen zu ermöglichen, mit integrierter Unterstützung von Webfeeds (auch als RSS oder Really Simple Syndication bezeichnet). RSS ist eine Technologie zum Abonnieren von Informationen, damit Sie nicht nach diesen suchen müssen. Über RSS-Abonnements erhalten Sie automatisch Listen (Feeds) von Überschriften aus Websites.
 
Internet Explorer erkennt diese Feeds zu Websites und ermöglicht, diese in einer Vorschau anzuzeigen und zu abonnieren. Nach der Abonnierung fasst Internet Explorer 7 Überschriften in jedem Feed automatisch in einer Liste zusammen. Dadurch können Sie neue Informationen auf verschiedenen Websites schnell durchsuchen, ohne die Websites einzeln besuchen zu müssen.
 
Features:
 
Ideal für private Anwender, begeisterte Mediennutzer, mobile Anwender und Familien
Die neue Oberfläche Windows Aero sorgt für mehr Übersichtlichkeit und Benutzerfreundlichkeit
Leistungsstarke integrierte Desktopsuchfunktionen, mit denen nahezu alles auf dem PC schnell gefunden werden kann
Unterstützt Minianwendungen, die sich mit Webdiensten verbinden, um Wetterberichte, aktualisierte Nachrichten, Straßenkarten oder Internetradio bereitzustellen
Schnelles und gezieltes Wechseln zwischen verschiedenen Fenstern mit Hilfe von Windows Flip 3D
Unterstützung neuester Spiele-Technologie durch DirectX 10
Windows Media Center bietet Zugriff auf Live- und aufgezeichnete Fernsehprogramme, Filme, Musik und Bilder - über Media Center-Erweiterungen sogar überall im Haus
Enthält Windows Media Player 11, die digitale Musiksoftware der nächsten Generation
Windows Defender schützt vor Spyware, Viren und Würmern
Der neue Benutzerkontoschutz verbindet die Flexibilität eines Administratorkontos mit der Sicherheit eines Benutzerkontos
Mehr Sicherheit und Komfort beim Surfen mit dem neuen Internet Explorer 7
Reaktivierung des PCs aus dem Ruhezustand in nur 2 bis 3 Sekunden
Unterstützt leistungsstarke Dual-Core-Systeme
";2;False;0;;;" Windows Vista Home Premium 32 Bit OEM ";microsoft-windows-vista-home-premium-oem-32-bit;True;True;P-2970;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;49.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39650,5243865741;"80;30;2095";3;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000109-microsoft-windows-vista-home-premium-oem-32-bit.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000110-microsoft-windows-vista-home-premium-oem-32-bit.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000111-microsoft-windows-vista-home-premium-oem-32-bit.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"Garmin Topo Österreich V2 ";"Garmin Topo Österreich V2 ";"

Garmin Topo  Österreich V2

 
Digitale topographische Vektorkarte-Originallizenz
 
 
Topo Österreich ist die perfekte Ergänzung für Ihr Garmin GPS!
Die neueste Version der beliebten Outdoor-Karte ist auf allen kartenfähigen Garmin GPS-Geräten lauffähig.
Die Topo Österreich bietet eine Vielzahl an Informationen wie Wanderwege, Straßen, Seen, Flüsse, Wälder,
Berggipfel sowie Höhenlinien im Abstand von 20m und mehr als 800 gespeicherte Positionen von Schutzhütten.
Die neue Topo Österreich ist mit einem digitalen Höhenmodell hinterlegt und erstmals auch routingfähig!
Planen Sie Ihre Touren, Routen und Wegpunkte am PC oder direkt am GPS-Gerät -
die Topo Österreich ist die perfekte Kartengrundlage für Wanderungen und Touren abseits der Straße!Tausende Points of Interest (Gasthäuser, Hotels, Parkplätze, Gemeindeämter ...)
Suchmöglichkeiten für Geonamen, POIs und Städte/Orte.
Auch abseits von Straßen auf Wegen und Pfaden routingfähig, sie folgt beim Anlegen von Routen automatisch den auf der Karte verzeichneten Wegen, was die Navigation deutlich vereinfacht
Dank der mitgelieferten MicroSD-Karte ist die Handhabung der Topo Österreich V2 sehr einfach:
MicroSD-Karte in Garmin Navigationsgerät einlegen ¿ fertig. Eine Onlinefreischaltung ist für die Nutzung mit MicroSD-Karte nicht erforderlich.
Höhenlinien im Abstand von 20m, mit anschaulicher Geländedarstellung
Komfortable Routen- & Wegpunktverwaltung
Einfache Übertragen von Wegpunkten, Routen & Tracks auf Garmin GPS Geräte
Gesamtdatenvolumen ca. 175 MB. Die Karte ist in 196 einzelne Kartenabschnitte unterteilt,
die zwischen 100 kB und 1,6 MB groß sind.
Lizenz zur Freischaltung eines Gerätes. Registrierung über Internet erforderlich.
Digitale topographische Vektorkarte Routenplanung: MapSource-Produkt -
die Kartendaten werden mit der Software MapSource bearbeitet.
";2;False;0;;;Garmin Topo CD Österreich;garmin-topo-oesterreich-v2;True;True;P-2030;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;189.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39650,5216550926;"67;2095";44;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000108-garmin-topo-osterreich-v2.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"TomTom ONE Europe Classic Edition TMC ";"TomTom ONE Europe Classic Edition TMC ";"

TomTom ONE Europe Classic Edition TMC 
 

TomTom ONE Classic Europe 42 Traffic mit RDS/TMC-Empfänger

 

Der neue ONE Classic Europe 42 Traffic mit EasyPort passt mit Saugnapfhalterung in jede Hemdtasche.
Ein 3,5-Zoll-Touchscreen, hervorragende Sprachqualität, TMC zur Stauumfahrung, TomTom Map Share, Hilfe!-Menü für Notfälle 
für die neueste Kartenversion und Kartenmaterial von West- und Osteuropa (42 Länder) machen dieses TomTom ONE Classic so einzigartig.
TomTom ONE Classic Europe 42 Traffic mit 3,5 Zoll Touchscreen, USB-Heimladegerät, einem RDS/TMC-Empfänger und QuickGPSfix-Funktion für eine sekundenschnelle Navigationsbereitschaft
vorinstalliertes Kartenmaterial von 32 Ländern aus Ost- und Westeuropa mit Kartenaktualisierung und eigener Kartenanpassung über TomTom HOME und Map Share
Navigieren von Haustür zu Haustür mit Details zu Adressen, Hausnummern, Tankstellen sowie Orten von besonderem Interesse (Points of Interest, POI), 3D- / 2D-Ansicht mit Tages- und Nachtansichtmodus
RDS/TMC-Verkehrsinfo-Empfänger für aktuelle Staumeldungen und Verkehrshinweise zum Umfahren schwieriger Verkehrssituationen und alternative Routen
Lieferumfang: TomTom One Classic Europe 42 Traffic, EasyPort-Halterung, USB-Kabel, Autoladegerät, Dokumentation, RDS/TMC-Empfänger
";2;False;0;;;;tomtom-one-europe-classic-edition-tmc;True;True;P-1990;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;130.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39650,5188541667;66;4;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000107-tomtom-one-europe-classic-edition-tmc.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;0;True;"TomTom Go 740 Live Navigationssystem ";"TomTom Go 740 Live Navigationssystem schwarz ";"
TomTom Go 740 Live Navigationssystem  schwarz
 
4,3 Zoll Touchscreen, 32+10 Länderkarten, TMC, Bluetooth

GO 740 LIVE mit 4,3 Zoll Farb-Touchscreen, 42 vorinstallierten Karten europäischer Länder (davon 10 Hauptverkehrsstraßen-Karten), Bluetooth,
Kfz-Freisprecheinrichtung sowie vielen Innovationen für eine verbesserte und komfortable Navigation
Sprachsteuerung, LIVE Services mit HD Traffic, Sicherheitswarnungen, Lokale Suche mit Google, Wetter, QuickGPSfix sowie Fahrspurassistent für komplizierte Spurenführungen
IQ Routes - Intelligente Routenberechnung aus aktuellsten Karten unter Berücksichtigung verschiedener Umweltfaktoren wie Tag, Uhrzeit, Straßenabschnitt, Durchschnittsgeschwindigkeiten etc.
Text-to-Speech zum Ansagen von Straßennamen und Verkehrshinweisen für einen konzentrierten Blick auf die Fahrbahn und ein entspanntes Fahren
Lieferumfang: TomTom GO 740 LIVE,Active-Dock Kfz-Halterung, Dockinghalterung für PC/Mac, Autoladegerät, Benutzerhandbuch, CD-ROM (TomTom HOME-Software)
";2;False;0;;;;tomtom-go-740-live-navigationssystem;True;True;P-1980;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;249.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39650,5165162037;66;4;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000106-tomtom-go-740-live-navigationssystem.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; +5;210;True;SmartStore Office;;"

Der Marketing- und Verkaufsmanager für ein erfolgreiches Online-Business

Kunden gewinnen, Kunden binden, Umsatz steigern


SmartStore Office ist die leistungsstarke Software-Lösung zur Steuerung Ihrer Online-Verkaufs- und Marketings-Aktivitäten. Auf bahnbrechend einfache und intelligente Weise ermöglicht sie:

 

 

  • Die Planung und Durchführung hocheffektiver Email-Marketing-Kampagnen zur Neukundengewinnung
  • Die Verwaltung und Abwicklung von Bestellungen für störungsfreie Abläufe in Ihrem BackOffice
  • Die rasche Umsetzung von Maßnahmen zur Kundenbindung
  • Eine wirksame Optimierung Ihres Online-Angebotes dank umfangreicher statistischer Auswertungen

SmartStore Office bietet eine hochmoderne und -intuitive Bedienerführung, die den Aufbau und das Organisieren des "perfekten" Online-Business zu einem Kinderspiel macht. Im SmartStore-typischen Point&Click-Verfahren können Sie auf einfachste Weise:

 

 

  • Professionelle HTML-Newsletter und Serien-Emails erstellen und an tausende Kontakte gleichzeitig versenden
  • Ihre Kunden, Interessenten, Partner und Mitglieder mit den neuesten Informationen rund um Ihr Angebot versorgen
  • Ihre Top-(Produkt)-Angebote mitsamt Abbildungen, Beschreibungen und Preisen mit einem Klick in Ihre Emailings integrieren
  • Den Inhalt Ihrer Emailings personalisieren
  • View- und Klick-Raten Ihrer Emailings auswerten
  • Durch gezielte Nachfassaktionen Folge-Geschäfte generieren
  • Ihre Online-Bestellungen abrufen und bearbeiten
  • Rechnungen, Lieferscheine und sonstige Berichte drucken oder direkt als Emails an Ihren Kunden senden

SmartStore Office ist die unverzichtbare Ergänzung zu unserer marktführenden und mehrfach ausgezeichneten Ecommerce-Komplettlösung SmartStore.biz. Die einzigartige Interaktion zwischen beiden Anwendungen erhöht die Erfolgsrate Ihres Online-Business erheblich:

  • Kunden, Interessenten und Newsletter-Abonnenten werden in einer zentralen Datenbank gespeichert. Sie verfügen dadurch automatisch über "reiche" Kontaktdaten, die absolut zielgerichtete und hocheffektive Email-Personalisierung ermöglichen.
  • Produkt-Informationen aus einem bestehenden SmartStore.biz Produktkatalog lassen sich automatisch in ein Emailing einfügen. Dabei kann jedes Produkt mit den Produkt-Detail-Informationen in Ihrem Online-Shop verlinkt werden.
  • Aussagefähige Auswertungen zu Newslettern, Kunden, Produkten, Umsätzen etc. geben Ihnen wertvolle Hinweise zur weitergehenden Optimierung Ihres Angebotes. Sie können bspw. das Klick-Verhalten Ihrer Leser auswerten, und so wertvolle Erkentnisse über evtl. geplante Nachfassaktionen gewinnen.
  • Keine Reibungsverluste, keine Insellösungen, keine lästige "Datenschieberei" mehr von Anwendung A nach B!
";2;False;0;;;SmartStore Office;smartstore-office;True;True;P-2950;;;False;0;False;;False;False;0;False;0;1;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;2;10000;False;False;5;1;1;0;False;1;10000;;False;False;False;False;99.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;38938,5373611111;"2095;81";42;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000095-smartstore-office.gif;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000096-smartstore-office.gif;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000097-smartstore-office.gif;1;;True;kg;2.0000;1;;False;False;False;;;;;False;;;;;; +5;210;True;SmartStore eBay SmartSeller;;"

Der clevere Verkaufsmanager für eBay!


eBay SmartSeller ist eine eCommerce-Anwendung, mit der Sie Ihre Produkte auf einfache und bequeme Weise auf dem Online-Marktplatz von eBay anbieten können. Verschiedene Module wie Kundenverwaltung, Fakturierung oder Nachrichten-Manager unterstützen Sie bei der Abwicklung verkaufter Produkte und übernehmen Aufgaben, die Sie sonst manuell erledigen müssten.

Direkter Zugang

eBay SmartSeller ermöglicht Ihnen einen direkten Zugang zum größten Online-Marktplatz der Welt, ohne langwieriges Mausklicken oder Suchen. Profitieren Sie von den allerneuesten eBay-Technologien; vereint in einer - durch eBay zertifizierten - Anwendung.

Kosten minimieren

Minimieren Sie Ihre Kosten, die Ihnen rund um Ihre eBay-Geschäfte entstehen. Mit eBay SmartSeller ist ein für alle mal Schluss mit versteckten oder zusätzlichen Kosten. Keine Drittanbieter, die an Ihren Umsätzen partizipieren. eBay berechnet Ihnen lediglich die allgemein üblichen Gebühren fürs Einstellen einer Auktion und die Provision, die bei einem erfolgreichen Abschluss anfällt. Über den eBay SmartSeller sind diese Gebühren voll transparent und zu jedem Zeitpunkt durch Sie nachvollziehbar.

Auktionen verwalten

Legen Sie beliebig viele Artikel an, wahlweise mit oder ohne Assistenten. Die Ordneransicht hilft Ihnen dabei, die Artikel zu ordnen, um selbst bei einer großen Artikelanzahl nicht den Überblick zu verlieren.

Starten Sie eine beliebige Anzahl von Auktionen, Festpreisverkäufen oder eBay-Shop-Einträgen. Der Clou dabei: Die Listings erscheinen im Datengitter schräg unterhalb Ihrer Artikel, d.h. Sie können ganz genau den Verlauf Ihrer Artikel über den Lebenszyklus von eBay-Auktionen hinweg mitverfolgen. Zusätzlich gewährleistet der Auktionsstatus, dass Sie stets den Überblick über Ihre eBay-Verkaufsaktivitäten behalten und sofort wissen, wann neue Auktionen gestartet werden müssen.

Zeitsparend abwickeln

eBay SmartSeller verfügt über eine umfangreiche Kundenverwaltung, in der Kunden und deren Rechnungen hierarchisch und übersichtlich präsentiert werden. Mit dem Rechnungsassistenten lassen sich komfortabel Rechnungen erstellen, drucken und betrachten. Und mit dem Mahnungsassistenten benachrichtigen Sie mit wenigen Klicks säumige Käufer. Darüber hinaus ermöglicht der Bewertungs-Manager die zügige Bewertungs-Abgabe: wahlweise für ausgewählte oder alle noch nicht bewerteten Transaktionen.

Professionelle Auktionsvorlagen

Im eBay SmartSeller integriert ist ein vollwertiger HTML-Editor, mit dem Sie das Aussehen Ihrer Auktionen gestalten können. Oder nutzen Sie einfach die mitgelieferten HTML-Vorlagen, die speziell für die Gestaltung von Auktionen entwickelt und auf das Kategorie-Angebot von eBay abgestimmt wurden. Einer professionellen Präsentation Ihrer Produkte und höherer Erfolgschancen Ihrer Auktionen stehen hier nichts mehr im Wege.

Beobachten und Bieten

Zum Beobachten und Bieten von Auktionen steht eine separates Modul zur Verfügung, über das individuelle Suchanfragen erstellt werden können. So filtern Sie gezielt alle für Sie relevanten Angebote aus dem Gesamtangebot bei eBay heraus und behalten die Übersicht über den Online-Marktplatz.

SmartStore.biz und SmartStore Office enabled

eBay SmartSeller kommuniziert reibungslos mit dem Shopsystem SmartStore.biz und dem Marketing- und Verkaufs-Manager SmartStore Office: Mit wenigen Klicks lassen sich in SmartStore.biz bereits erfasste Artikel-Daten übernehmen; ebenso einfach lassen sich Kunden und Bestellungen zur weiteren Abwicklung nach SmartStore Office übergeben. ";2;False;0;;;SmartStore eBay SmartSeller;smartstore-ebay-smartseller;True;False;P-2940;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;79.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;38938,5365625;"29;2095;81";42;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000090-smartstore-ebay-smartseller.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000091-smartstore-ebay-smartseller.gif;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000092-smartstore-ebay-smartseller.gif;1;;False;;;;;False;False;False;;;;;False;;;;;; +5;210;True;SmartStore.biz 5;;"
Achtung, Fertig, Klick!
Das Mega-Update SmartStore.biz 5

Es ist soweit! Mit SmartStore.biz 5 geht eine Revolution im Bereich Desktop- basierender Online-Shop-Systeme an den Start.

Alles ist neu, besser, größer, einfacher!

SmartStore.biz ist in der Version 5 komplett neu entwickelt worden. Dabei wurden bewährte Programmabschnitte ausgebaut, viele bahnbrechend neue Funktionen implementiert und verbesserte Bedienungsabläufe ausgearbeitet. Nie zuvor war es so einfach, einen hochwertigen und modernen Online-Shop zu gestalten und zu organisieren.

SmartStore.biz 5 bietet für das individuelle Erscheinungsbild eines Online-Shops unzählige Variationen im Bereich Layout & Design, eine schnelle und unkomplizierte Produktverwaltung und darüber hinaus ein herausragendes Content-Management.

Eines der größten Highlights ist das integrierte WYSIWYG-Redaktionssystem mit nahezu unbegrenzten Möglichkeiten, den eigenen Online-Shop inhaltlich zu gestalten. Hand in Hand mit dem neuen Designer und einer Auswahl mitgelieferter Designvorlagen verleihen Sie Ihrem Shop per Klick ein höchst anspruchsvolles Look & Feel.

Nahtlos in die inhaltliche Gestaltung eingebunden ist auch der stark ausgebaute Produktmanager. Auf einfachste Weise sorgt das Zusammenspiel beider Bereiche für eine perfekte Produktpräsentation und ist die optimale Voraussetzung für einen erfolgreichen Online-Shop.

SmartStore.biz 5 ist von Haus bereits optimal für Suchmaschinen optimiert und erstellt für die maximale Präsenz zudem Webpfade aus lesbaren und völlig frei konfigurierbaren Namen für Verzeichnisse und Dateien. Die aussagekräftigen Linkpfade unterstützen dabei auch den Besucher der Seiten bei seiner Navigation durch den Katalog.

";2;False;0;;;SmartStore.Biz 5;smartstorebiz-5;True;True;P-2930;;;False;0;False;169;True;False;0;False;0;1;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;1;10000;False;True;1;1;1;0;False;1;10000;;False;False;False;False;149.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;38938,536400463;"29;81;2095";42;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000088-smartstorebiz-5.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000089-smartstorebiz-5.png;;1;;False;ounce;;;;False;False;False;;;;;False;;;;;; From a2e5001f85843bd6620da79b0bbe77a6ea869dda Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Thu, 10 Dec 2015 15:01:15 +0100 Subject: [PATCH 074/626] Git ignore temp import files --- .gitignore | 1 + .../Content/1-165-0001-produktcsvexport.csv | 219 ------------------ 2 files changed, 1 insertion(+), 219 deletions(-) delete mode 100644 src/Presentation/SmartStore.Web/App_Data/ImportProfiles/produkte-importieren/Content/1-165-0001-produktcsvexport.csv diff --git a/.gitignore b/.gitignore index 460b0b95df..da52db8b44 100644 --- a/.gitignore +++ b/.gitignore @@ -201,6 +201,7 @@ Kopie von* /src/Presentation/SmartStore.Web/Plugins /src/Presentation/SmartStore.Web/App_Data/_temp/ /src/Presentation/SmartStore.Web/App_Data/ExportProfiles/ +/src/Presentation/SmartStore.Web/App_Data/ImportProfiles/ /src/Presentation/SmartStore.Web/App_Data/Settings.txt /src/Presentation/SmartStore.Web/App_Data/InstalledPlugins.txt /src/Presentation/SmartStore.Web/App_Data/Licenses.lic diff --git a/src/Presentation/SmartStore.Web/App_Data/ImportProfiles/produkte-importieren/Content/1-165-0001-produktcsvexport.csv b/src/Presentation/SmartStore.Web/App_Data/ImportProfiles/produkte-importieren/Content/1-165-0001-produktcsvexport.csv deleted file mode 100644 index 4750e5d752..0000000000 --- a/src/Presentation/SmartStore.Web/App_Data/ImportProfiles/produkte-importieren/Content/1-165-0001-produktcsvexport.csv +++ /dev/null @@ -1,219 +0,0 @@ -ProductTypeId;ParentGroupedProductId;VisibleIndividually;Name;ShortDescription;FullDescription;ProductTemplateId;ShowOnHomePage;HomePageDisplayOrder;MetaKeywords;MetaDescription;MetaTitle;SeName;AllowCustomerReviews;Published;SKU;ManufacturerPartNumber;Gtin;IsGiftCard;GiftCardTypeId;RequireOtherProducts;RequiredProductIds;AutomaticallyAddRequiredProducts;IsDownload;DownloadId;UnlimitedDownloads;MaxNumberOfDownloads;DownloadActivationTypeId;HasSampleDownload;SampleDownloadId;HasUserAgreement;UserAgreementText;IsRecurring;RecurringCycleLength;RecurringCyclePeriodId;RecurringTotalCycles;IsShipEnabled;IsFreeShipping;AdditionalShippingCharge;IsEsd;IsTaxExempt;TaxCategoryId;ManageInventoryMethodId;StockQuantity;DisplayStockAvailability;DisplayStockQuantity;MinStockQuantity;LowStockActivityId;NotifyAdminForQuantityBelow;BackorderModeId;AllowBackInStockSubscriptions;OrderMinimumQuantity;OrderMaximumQuantity;AllowedQuantities;DisableBuyButton;DisableWishlistButton;AvailableForPreOrder;CallForPrice;Price;OldPrice;ProductCost;SpecialPrice;SpecialPriceStartDateTimeUtc;SpecialPriceEndDateTimeUtc;CustomerEntersPrice;MinimumCustomerEnteredPrice;MaximumCustomerEnteredPrice;Weight;Length;Width;Height;CreatedOnUtc;CategoryIds;ManufacturerIds;Picture1;Picture2;Picture3;DeliveryTimeId;QuantityUnitId;BasePriceEnabled;BasePriceMeasureUnit;BasePriceAmount;BasePriceBaseAmount;BundleTitleText;BundlePerItemShipping;BundlePerItemPricing;BundlePerItemShoppingCart;BundleItemSkus;AvailableStartDateTimeUtc;AvailableEndDateTimeUtc;StoreIds;LimitedToStores;Name[DE];ShortDescription[DE];FullDescription[DE];Name[en];ShortDescription[en];FullDescription[en] -5;0;True;_Zero Price;;"

Optisch zum Verwechseln ähnlich, ebenso kompakt und leicht wie die erfolgreiche SD19, aber mit noch besserer Auflösung, präsentiert sich die brandneue AEE SD21 PRO Action-Cam. Die SD21 PRO ist eine komplette Neuentwicklung, mit Innovationen und einer Ausstattung, die es bisher in diesem Preissegment noch nicht gab.
Bei der SD21 PRO ist die Monitor-Rückwand wie auch die Fernbedienung ebenso selbstverständlich wie der aufsteckbare Zusatzakku für noch längere Power.
Für einfaches, unkompliziertes Justieren der Kamera ist ein Laserpointer integriert. Der 10-fach Digitalzoom und die hochwertige Optik garantieren für optimale Aufnahmeergebnisse bei allen Bedingungen.

Highlights SD21 PRO:

  • 1/3 Zoll CMOS-Sensor 8,0 Megapixel
  • 170° Weitwinkel-Objektiv, Blende F/3.0
  • 10x Digitalzoom
  • Automatische Belichtung und Weissabgleich
  • Externes TFT-Display mit Echtzeit-Anzeige für Video und das Abspielen aufgezeichneter Inhalte
  • Laserpointer als Aufnahmeorientierung
  • Selbst-/Zeit-Auslöser mit Kontroll-LED
  • Eingebautes Mikrofon für hochwertige Stereo-Voice-Aufnahmen
  • Wasserdichtes Gehäuse bis 60 Meter (IP68-Standard)
  • Hochleistungs-Lithium-Batterie
  • Aufsteckbarer Zusatzakku mit eigener Ladestandsanzeige - verdoppelt die Aufnahmedauer
  • Auto Stand-by zur Energieeinsparung
  • Funktionen: HD-Videoaufnahme / Foto
  • Recording MOV Videos können direkt am PC wiedergegeben oder auf Video-Websites hochgeladen werden
  • Photo 180-Grad-Umkehr-Funktion
  • Externe Micro SD/MMC-Speicherkarte, unterstützt bis max. 64GB (nicht enthalten)
  • Speicherkapazität Alarm
  • Schneller Vor- und Rücklauf, Funktion zum Überspringen von Inhalten in das nächste Segment
  • Unterstützung USB2.0
  • HDMI-Ausgang, AV-OUT-Funktion
  • Support-System: Windows 98SE/2000/Me/XP/Vista/Win 7/Mac OS

Grösse: ca. 61x43x40mm (BxHxT)

Gewicht: 88g ohne Bildschirm, 112g mit Bildschirm

Technische Daten SD21 PRO:

  • Auflösung/Sensor: 8.0M CMOS-Sensor (3200 * 2400)
  • Optik / Linse: 170° Weitwinkel-Objektiv, Blende F/3.0
  • Gehäuse: IP68 wasserdichtes Gehäuse bis 60m
  • Memory-Karte: Micro SD unterstützt bis 64GB (nicht enthalten)
  • Photo-Modus: 3M (2048 * 1536) / 5M (2560 * 1920) / 8M (3200 * 2400)
  • Video-Aufnahmemodus: 1080P 720P WVGA QVGA
  • Bildrate: 1080P/30fps 720P/30fps WVGA/60fps QVGA/30fps
  • Video-Aufnahmeformat: MOV (H.264-Video-Kompression)
  • Photo-Format: JPEG
  • Aufnahmekapazität (2GB SDKarte):
  • Photos 3M (1900pcs), 5M (1160pcs), 8M (770pcs) /
  • Videos: 720P/60min, WVGA/135min
  • Laserpointer/Laserleistung: 1MW
  • AV OUT: Unterstützung NTSC / PAL VGA und HDMI
  • USB: USB2.0
  • Mikrofon: 2 Mikrofone, eingebaute
  • Leistungsaufnahme: 500mA@3.7V (MAX)
  • Lithium-Batterie: 1000mAh
  • Batterielaufzeit: 2.5h / Batterie
  • Betriebssystem: Windows XP SP2/Vista oder höher / Mac OS. CPU:
  • Pentium4 1.5GHZ oder höher RAM: min. 1GB
  • RTC-Funktion: Unterstützung
  • Lagertemperatur: -20 bis -60 
  • Betriebstemperatur: -10 bis -50 
  • Luftfeuchtigkeit bei Betrieb: 15 85% RH

 

";2;True;0;;;_Wasser;_zero-price-3;True;True;;;;False;0;False;;False;False;0;False;0;1;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;0;False;False;0;0;1;0;False;1;10000;;False;True;False;False;0.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;42302,5461930208;"1;2095";;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000696-_zero-price.jpg;;;2;;True;l;35.0000;100;;False;False;False;;;;1;True;;;;;; -5;0;True;Bundle Item 2;;;2;False;0;;;;bundle-item-2;True;True;;;;False;0;False;;False;False;0;True;10;1;False;;False;;False;100;0;10;True;False;0,0000;False;False;1;0;10000;False;False;0;0;0;0;False;1;10000;;False;False;False;False;19.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;41965,4767811343;;;;;;;;False;ounce;;;;False;False;False;;;;;False;;;;;; -5;0;True;Bundle Item 1;;;2;False;0;;;;bundle-item-1;True;True;;;;False;0;False;;False;False;0;True;10;1;False;;False;;False;100;0;10;True;False;0,0000;False;False;1;0;0;False;False;0;0;0;0;False;1;10000;;False;False;False;False;84.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;41965,4671613079;;;;;;;;False;ounce;;;;False;False;False;;;;;False;;;;;; -5;0;True;_Download;;"

Downloadable product.

";2;False;0;;;;_download;True;True;;;;False;0;False;;False;True;8;True;10;1;False;;False;;False;100;0;10;False;False;0,0000;False;False;1;0;10000;False;False;0;0;1;0;False;1;10000;;False;False;False;False;3.8000;0.0000;0.0000;;0.0;0.0;False;0.0000;1000.0000;0.0000;0.0000;0.0000;0.0000;41863,7438013542;"1;2095";;;;;;;False;ounce;;;;False;False;False;;;;;False;;;;;; -5;0;True;_Attribut Test;;"

Continually incubate standards compliant content vis-a-vis multifunctional portals. Dynamically exploit collaborative strategic theme areas vis-a-vis extensive partnerships. Monotonectally maximize user friendly relationships for backward-compatible alignments. Objectively deliver covalent opportunities after exceptional scenarios. Objectively drive backend paradigms via excellent meta-services. Uniquely customize sticky core competencies rather than leveraged internal or "organic" sources. Objectively conceptualize client-based users without customer directed applications. Continually generate backend processes and market-driven markets. Proactively evisculate visionary testing procedures with fully tested networks. Collaboratively facilitate B2C schemas vis-a-vis covalent meta-services. Proactively recaptiualize progressive quality vectors vis-a-vis frictionless supply chains. Distinctively synthesize revolutionary leadership vis-a-vis strategic e-markets. Distinctively pontificate principle-centered benefits with pandemic resources. Professionally pontificate multifunctional strategic theme areas via low-risk high-yield data. Uniquely underwhelm technically sound information before functional synergy. Progressively utilize 24/365 ROI whereas client-based interfaces. Seamlessly reintermediate alternative customer service through plug-and-play quality vectors. Professionally repurpose one-to-one scenarios without visionary supply chains. Enthusiastically unleash timely applications after an expanded array of e-commerce. Monotonectally pursue virtual intellectual capital after high standards in scenarios. Professionally benchmark end-to-end internal or "organic" sources with maintainable supply chains. Authoritatively disseminate high-payoff imperatives for stand-alone infomediaries. Completely network stand-alone initiatives for market positioning intellectual capital. Appropriately deliver process-centric collaboration and idea-sharing after multifunctional leadership. Energistically unleash open-source vortals vis-a-vis transparent niches.

";2;False;0;;;;ab-22;True;True;SKU-Tester;;;False;0;False;;False;False;7;True;10;1;False;;False;;False;100;0;10;True;False;0,0000;False;False;1;2;10000;True;False;0;1;1;0;False;1;10000;;False;False;False;False;0.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;1000.0000;0.0000;0.0000;0.0000;0.0000;41833,6856570949;"1;2095";;;;;2;;False;ounce;;;;False;False;False;;;;;False;;;;;; -5;0;True;_GiftCard;;

GiftCart for testing.

;2;False;0;;;;_giftcard-2;True;True;;;;True;0;False;;False;False;0;True;10;1;False;;False;;False;100;0;10;False;False;0,0000;False;False;1;0;10000;False;False;0;0;1;0;False;1;10000;;False;False;False;False;10.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;1000.0000;0.0000;0.0000;0.0000;0.0000;41701,4763476505;1;;;;;;;False;ounce;;;;False;False;False;;;;;False;;;;;; -5;0;True;GiftCard;;;2;False;0;;;;_giftcard;True;True;;;;True;0;False;;False;False;0;True;10;1;False;;False;;False;100;0;10;True;False;0,0000;False;False;1;0;10000;False;False;0;0;1;0;False;1;10000;;False;False;False;False;10.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;1000.0000;0.0000;0.0000;0.0000;0.0000;41671,8425473727;2095;;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000666-giftcard.jpg;;;;;False;ounce;;;;False;False;False;;;;;False;;;;;; -15;0;True;_SmartStore Bundle;;"

SmartStore Test Bundle

";2;False;0;;;_SmartStore Bundle;_smartstore-bundle;True;True;PD-01097;;;False;0;False;;False;False;0;False;0;1;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;888.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;41656,6659837963;"81;2095";;;;;1;;False;;;;Bestehend aus;False;False;True;;;;;False;;;;;; -15;0;True;_Bundle;;"

My product bundle.

";2;False;0;;;;_bundle;True;True;SKU-1001;;;False;0;False;;False;False;0;True;10;1;False;;False;;False;100;0;10;True;False;0,0000;False;False;1;1;9999;False;False;10;0;1;1;False;1;10000;;False;False;False;False;499.0000;0.0000;260.6000;;0.0;0.0;False;0.0000;1000.0000;0.0000;0.0000;0.0000;0.0000;41656,5811581829;"81;2095";;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000665-_bundle.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000667-_bundle.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000668-_bundle.jpg;2;;False;kg;3.0000;1;Bestehend aus;False;False;True;P-6000,P-2930,P-2940,P-2950;;;;False;;;;;; -10;0;True;_Gruppenprodukt;Grouped product;"

Tortor dis facilisis augue eros. Porta turpis! Augue! Magna mattis porttitor aliquet eu, montes magna nunc pulvinar hac, augue porttitor, ridiculus! Pulvinar, in tortor risus in scelerisque platea, pulvinar pid! Dapibus proin diam. Pellentesque cum! Tincidunt, tempor a magna turpis, mid amet, aenean, placerat. Phasellus? Tempor, cursus lacus porttitor ac, in tincidunt sociis vel? Eu velit dapibus integer enim risus augue phasellus odio turpis, sociis, eros dapibus et sed auctor, nec nisi montes, egestas integer eu rhoncus tortor integer montes sit scelerisque nec integer! Vel aliquet vut aliquet dis integer sed urna lectus sed habitasse etiam! Nunc purus augue dictumst, lectus platea? Turpis montes cras ultricies, adipiscing? Nunc. Cursus in! In ultricies parturient etiam augue, tempor mauris pellentesque purus rhoncus.

Vut vut et amet, phasellus? Et in integer enim, aenean elit, montes cum elementum nascetur a penatibus! Ac magna lorem ac placerat, lectus. Scelerisque habitasse elementum sociis scelerisque rhoncus. Natoque mattis parturient tempor dictumst turpis, hac placerat dolor nunc penatibus. Facilisis tristique massa facilisis? Rhoncus habitasse sit! Aenean aliquet ut quis ut in amet ut, phasellus augue sit tempor nunc dictumst eu, porta amet augue, mattis facilisis ac! Turpis egestas ridiculus, lacus in, sed placerat, odio lundium tincidunt nisi amet rhoncus. Augue cras! Velit, mattis! Auctor nisi mus? Amet nunc elementum placerat vut! Porttitor pid porta amet sit magnis, nisi ut cursus. Egestas sed auctor amet nec sit dapibus amet dis? Odio velit ac, hac cum ridiculus, amet ac.

Integer nisi natoque dictumst, facilisis! Phasellus turpis, pellentesque in! Dictumst pid, nisi a porttitor nec. Nunc natoque magnis etiam odio a diam vut integer aenean magnis cum lundium aenean, risus scelerisque, penatibus! Enim enim, scelerisque non placerat ut auctor, ac parturient auctor tincidunt, porttitor a est sit, nascetur scelerisque lorem in turpis sagittis mus! Enim turpis hac dis? Sit, porta nunc rhoncus ac? Integer tincidunt est porttitor, tincidunt natoque facilisis, facilisis, hac lorem elementum pulvinar tincidunt odio, dignissim cursus, urna auctor magna aliquam! Dolor duis ac tincidunt, magna! A! Urna, enim nascetur cursus, tincidunt aenean ac dis odio vel, ut lacus, duis sed in porttitor massa penatibus enim penatibus integer, augue urna scelerisque nunc elementum tincidunt duis tortor etiam.

Parturient pulvinar, lacus ut ultrices rhoncus massa! Velit et elementum pulvinar. Urna, magna integer. Nunc hac rhoncus? Amet eu? Sit in ac tortor. Lundium, pulvinar porttitor, tortor! Eros eu. Enim velit tristique elementum? Risus auctor tincidunt vut phasellus pellentesque! Turpis rhoncus vut, purus vel. Nunc ac augue! Ac sagittis pulvinar, in, duis adipiscing, velit sagittis? Penatibus mus scelerisque, nec! Dapibus scelerisque, augue turpis aenean, platea, urna integer risus a aliquet sagittis mid est elementum. Scelerisque? Tincidunt, vel vel natoque. Proin pulvinar sed placerat, cum amet nascetur scelerisque penatibus, ut, amet mus, duis placerat ac mus nec turpis facilisis dolor. Ultrices platea! Et magna enim rhoncus adipiscing odio, platea velit. Purus nunc duis! Enim velit integer facilisis nec? Diam mus.

Habitasse purus, sed vut cras non porta tincidunt facilisis, tristique, urna integer risus risus magna dictumst dignissim etiam mid! Vut risus lacus placerat, nunc a tincidunt, sociis est elementum, rhoncus pid, ridiculus quis nunc? In est scelerisque dignissim proin tortor sed, quis aenean! Et placerat in vut, risus! Augue. Lundium pid. Sit elit! Sed lorem mus ac pulvinar sit integer odio dignissim montes, adipiscing magna adipiscing porta nunc nascetur sit. Quis tortor ridiculus, in, vut tincidunt urna mus, pulvinar a! Enim arcu nec ultricies lacus sagittis mattis mauris dictumst, magna amet habitasse ut et ac! Ac amet dolor scelerisque. Auctor sit eu vut ac, velit massa tempor! Montes, dis odio quis, magna ac, phasellus purus scelerisque etiam odio penatibus.

Nec habitasse rhoncus. Pulvinar, et porta, porta tristique odio ut, massa! Purus phasellus eros porttitor, aliquet nascetur, montes turpis? Magna scelerisque rhoncus in dapibus, lundium porttitor, augue, ut placerat. Habitasse dictumst ac cursus pulvinar pid platea. Nascetur cum augue urna nunc? Magnis, arcu, pid pulvinar, natoque sed? In parturient porttitor facilisis mauris sed? Nec cras, urna et augue tristique, tincidunt tortor auctor non? Amet magna et aliquam sit sed, mid, augue pid massa sit tincidunt placerat placerat massa montes magna dapibus, ut pulvinar hac urna parturient nec dolor nunc, tristique nec proin amet ultricies magna, sociis vel etiam dolor? Augue vel augue rhoncus rhoncus enim pid tristique sit porta sit augue, tristique adipiscing! Dignissim, dictumst aliquam lundium rhoncus turpis.

Mattis platea mauris, etiam duis amet, phasellus massa, mattis, nunc sed massa integer etiam mid dis velit in sagittis vel? Mauris. Enim mid integer, lundium! Mid pid aenean mattis elementum, nunc dis etiam augue augue vel, vel rhoncus tincidunt purus porta pellentesque, pid eu aliquet, ultricies tempor sociis? Dolor! Ac ultrices ultricies! Nec enim! Mauris lorem duis magna tincidunt, vel cursus dis. Pellentesque, urna, mid integer et ac lectus elit velit lectus scelerisque mauris nunc. Aliquet platea adipiscing, sagittis urna dolor vel rhoncus a duis, ac nec diam tincidunt odio! Hac porttitor sed ac parturient purus mauris, urna etiam, nec diam magna pellentesque turpis placerat magnis eros ridiculus, elementum lorem, tempor natoque? Ultrices sed nec dapibus eu rhoncus penatibus? Urna.

Quis dolor elementum mauris! Ridiculus, auctor in, tortor ut risus velit pulvinar, porta urna rhoncus magna ultrices! Proin integer, cras rhoncus pid integer, nec odio ac, et? Dictumst pulvinar enim adipiscing facilisis ac mid nec? Pulvinar et non tristique! Sit pulvinar, pulvinar penatibus tincidunt, habitasse integer nunc! Tincidunt amet natoque facilisis aliquam tortor. Etiam duis tristique arcu egestas, et, sagittis nec ac aliquam pulvinar aliquet, adipiscing, nisi, sit sit, egestas risus. Ac. Adipiscing elit sit turpis in nec amet, nec in porta sed. Vel in in sit ultricies. Risus. Cum nascetur integer risus phasellus? Lacus mid auctor enim, enim scelerisque elementum vut a, diam eros sit duis, nascetur magna, est in dignissim adipiscing. Quis. Enim sociis egestas? Ut scelerisque.

Elit placerat turpis, porttitor penatibus phasellus! In magnis eros ut, turpis? Pid? Odio et et, mauris aenean, purus turpis, adipiscing aliquet sed tortor! Turpis dapibus amet augue ut turpis montes mauris aliquam! Penatibus est, sagittis amet nunc ultrices ultrices, amet massa enim aliquam vel odio? Purus turpis? Urna tincidunt! Elementum magna integer enim, porttitor sed aenean mus phasellus vut lorem in ac sociis, in aenean, est! Adipiscing placerat tristique, nec nunc risus turpis. Ut, porta tincidunt dapibus, dignissim? Rhoncus turpis, enim massa massa platea magnis augue amet? Sit, rhoncus, augue magna aenean lorem a et. Cum lorem. Ultrices, duis! Ultrices etiam augue ridiculus! Adipiscing? Egestas elementum magna pulvinar augue, porta elementum aliquet et facilisis phasellus auctor adipiscing lacus tincidunt.

Nec porta scelerisque ut ac etiam ac lorem cursus urna risus, amet egestas, tristique, etiam vut, adipiscing! Nunc cum habitasse pulvinar eros purus eros turpis in nascetur, habitasse adipiscing. Mattis. Nisi augue turpis, tortor, integer? Velit dis et, tristique augue. Scelerisque elementum adipiscing velit phasellus cras risus tincidunt ut rhoncus montes, scelerisque, ultricies. Et nascetur? Dis adipiscing. Natoque, turpis? Augue facilisis, dapibus augue? Elementum, tortor ac. Integer, nunc dictumst, diam nunc, augue nec non. Risus odio. Odio amet ultrices! Et urna nisi magna nisi nunc pulvinar habitasse facilisis in nunc velit natoque placerat rhoncus auctor? Magna pulvinar pulvinar augue, elementum adipiscing! Nascetur augue! Eros mus, nisi porta integer sed cras porttitor scelerisque. Pulvinar lorem turpis! Etiam, dictumst ac elit.

Vel augue placerat tempor nunc tortor purus, egestas ut lacus massa quis nec non odio amet, tincidunt parturient nunc urna eros turpis ridiculus cursus penatibus mattis penatibus augue sed! Montes scelerisque. Et dictumst adipiscing lundium, tristique, enim nascetur, cum? Non pellentesque! Mauris magna sit, porttitor, magnis, vel, nisi ultrices velit! Pellentesque, amet augue mid placerat dignissim ac etiam scelerisque, ultrices purus etiam enim, scelerisque sit turpis montes porta nunc cras enim. Non risus in enim mattis nunc. Etiam adipiscing porttitor. Massa, nunc ultricies placerat enim. Est phasellus egestas porttitor. Et et elementum tempor ac? Proin! Augue tempor cras, eros! Rhoncus scelerisque auctor eu eu, diam? Nunc egestas, lectus cum, scelerisque, elementum, scelerisque magna, tempor elit arcu dictumst? Dis elementum.

Nascetur, cras cras ridiculus lorem ac lectus enim proin odio sit lectus lorem dapibus enim. Ac nisi porttitor aliquet aliquam aenean non lacus, rhoncus pulvinar tempor dapibus dolor aliquam. In, in tincidunt penatibus cras et, lundium, sed turpis sit nunc odio, phasellus rhoncus urna facilisis platea adipiscing, mid etiam nascetur, enim, vut elementum, duis et ridiculus, penatibus urna non? Aliquam turpis augue phasellus risus diam egestas penatibus vel dignissim dignissim, ut! Elementum pulvinar et nascetur dapibus enim lundium hac platea scelerisque pellentesque facilisis! Quis, scelerisque pulvinar aliquet tincidunt elementum aliquam velit? Eros mid in facilisis, porttitor augue mattis ut, elementum placerat! Adipiscing ut augue! Facilisis in facilisis porttitor penatibus! Vel urna ridiculus magna, integer? Amet, penatibus cursus porttitor nisi.

";1;False;0;;;;_gruppenprodukt-2;True;True;SKU-1000;;;False;0;False;;False;False;0;True;10;1;False;;False;;False;100;0;10;True;False;0,0000;False;False;1;0;9999;False;False;0;0;1;0;False;1;10000;;False;False;False;False;0.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;41645,6860016551;"2095;1;81";;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000672-_gruppenprodukt.jpg;;;;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;_Wasser;;"

Optisch zum Verwechseln ähnlich, ebenso kompakt und leicht wie die erfolgreiche SD19, aber mit noch besserer Auflösung, präsentiert sich die brandneue AEE SD21 PRO Action-Cam. Die SD21 PRO ist eine komplette Neuentwicklung, mit Innovationen und einer Ausstattung, die es bisher in diesem Preissegment noch nicht gab.
Bei der SD21 PRO ist die Monitor-Rückwand wie auch die Fernbedienung ebenso selbstverständlich wie der aufsteckbare Zusatzakku für noch längere Power.
Für einfaches, unkompliziertes Justieren der Kamera ist ein Laserpointer integriert. Der 10-fach Digitalzoom und die hochwertige Optik garantieren für optimale Aufnahmeergebnisse bei allen Bedingungen.

Highlights SD21 PRO:

  • 1/3 Zoll CMOS-Sensor 8,0 Megapixel
  • 170° Weitwinkel-Objektiv, Blende F/3.0
  • 10x Digitalzoom
  • Automatische Belichtung und Weissabgleich
  • Externes TFT-Display mit Echtzeit-Anzeige für Video und das Abspielen aufgezeichneter Inhalte
  • Laserpointer als Aufnahmeorientierung
  • Selbst-/Zeit-Auslöser mit Kontroll-LED
  • Eingebautes Mikrofon für hochwertige Stereo-Voice-Aufnahmen
  • Wasserdichtes Gehäuse bis 60 Meter (IP68-Standard)
  • Hochleistungs-Lithium-Batterie
  • Aufsteckbarer Zusatzakku mit eigener Ladestandsanzeige - verdoppelt die Aufnahmedauer
  • Auto Stand-by zur Energieeinsparung
  • Funktionen: HD-Videoaufnahme / Foto
  • Recording MOV Videos können direkt am PC wiedergegeben oder auf Video-Websites hochgeladen werden
  • Photo 180-Grad-Umkehr-Funktion
  • Externe Micro SD/MMC-Speicherkarte, unterstützt bis max. 64GB (nicht enthalten)
  • Speicherkapazität Alarm
  • Schneller Vor- und Rücklauf, Funktion zum Überspringen von Inhalten in das nächste Segment
  • Unterstützung USB2.0
  • HDMI-Ausgang, AV-OUT-Funktion
  • Support-System: Windows 98SE/2000/Me/XP/Vista/Win 7/Mac OS

Grösse: ca. 61x43x40mm (BxHxT)

Gewicht: 88g ohne Bildschirm, 112g mit Bildschirm

Technische Daten SD21 PRO:

  • Auflösung/Sensor: 8.0M CMOS-Sensor (3200 * 2400)
  • Optik / Linse: 170° Weitwinkel-Objektiv, Blende F/3.0
  • Gehäuse: IP68 wasserdichtes Gehäuse bis 60m
  • Memory-Karte: Micro SD unterstützt bis 64GB (nicht enthalten)
  • Photo-Modus: 3M (2048 * 1536) / 5M (2560 * 1920) / 8M (3200 * 2400)
  • Video-Aufnahmemodus: 1080P 720P WVGA QVGA
  • Bildrate: 1080P/30fps 720P/30fps WVGA/60fps QVGA/30fps
  • Video-Aufnahmeformat: MOV (H.264-Video-Kompression)
  • Photo-Format: JPEG
  • Aufnahmekapazität (2GB SDKarte):
  • Photos 3M (1900pcs), 5M (1160pcs), 8M (770pcs) /
  • Videos: 720P/60min, WVGA/135min
  • Laserpointer/Laserleistung: 1MW
  • AV OUT: Unterstützung NTSC / PAL VGA und HDMI
  • USB: USB2.0
  • Mikrofon: 2 Mikrofone, eingebaute
  • Leistungsaufnahme: 500mA@3.7V (MAX)
  • Lithium-Batterie: 1000mAh
  • Batterielaufzeit: 2.5h / Batterie
  • Betriebssystem: Windows XP SP2/Vista oder höher / Mac OS. CPU:
  • Pentium4 1.5GHZ oder höher RAM: min. 1GB
  • RTC-Funktion: Unterstützung
  • Lagertemperatur: -20 bis -60 
  • Betriebstemperatur: -10 bis -50 
  • Luftfeuchtigkeit bei Betrieb: 15 85% RH

 

";2;True;0;;;_Wasser;_wasser;True;True;;;;False;0;False;;False;False;0;False;0;1;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;2;0;False;False;0;0;1;0;False;1;10000;;False;True;False;False;0.9900;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;41540,3761458333;"1;2095";;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000673-_wasser.jpg;;;2;;True;l;35.0000;100;;False;False;False;;;;1;True;;;;;; -5;0;True;Apple MacBook Pro MD313D/A 13,3 Zoll Notebook;3 GB, 18 Zoll, 500 GB, Intel, 4;"
Apple MacBook Pro MD313D/A 13,3 Zoll Notebook
Intel Core i5  2x 2,40 GHz
 
Bis zu 2x schnellere Prozessoren. Bis zu 3x schnellere Grafik.
Quad-Core und Dual-Core Intel Prozessoren der nächsten Generation.
Das 13"" MacBook Pro gibt es jetzt mit einem 2,4 GHz Intel Core i5 Prozessor oder dem schnellsten Dual-Core Prozessor, den es gibt: dem 2,8 GHz Intel Core i7. Diese Prozessoren bieten Turbo Boost Geschwindigkeiten und machen das 13"" MacBook Pro bis zu doppelt so schnell wie die Vorgängergeneration.
 
Aber nur schnell ist uns nicht genug. Deshalb bieten die neuen 15"" und 17"" Modelle Quad-Core Leistung für praktisch alles, was du machen willst. Auch ein 2,4 GHz Quad-Core Intel Core i7 Prozessor mit Turbo Boost Geschwindigkeiten und bis zu 8 MB gemeinsam genutztem L3-Cache ist verfügbar. Auf MacBook Pro Modellen mit diesem Prozessor laufen Programme bis zu doppelt so schnell wie auf der besten Vorgängerkonfiguration.
 
Die Grafikleistung, die du brauchst, wenn du sie brauchst.
Alle MacBook Pro Modelle haben jetzt einen integrierten Intel HD Graphics 3000 Prozessor für die täglichen Aufgaben. Er codiert Videos schnell, ermöglicht HD Videotelefonate mit FaceTime und vieles mehr. Und auch Decodieren erledigt er effizienter, was bedeutet, dass du richtig lange DVDs und iTunes Filme schauen kannst.
 
Bei anspruchsvollen Grafikprogrammen wechseln die 15"" und 17"" MacBook Pro Modelle automatisch den Grafikprozessor und arbeiten mit den neuen leistungsstarken AMD Radeon Grafikprozessoren. Diese bieten verglichen mit den Vorgängermodellen die bis zu 3-fache Leistung.3 So siehst du bei 3D Spielen mehr Bilder pro Sekunde oder kannst schneller als je zuvor an HD Videoprojekten arbeiten.
 
Das neue Thunderbolt. Die schnellste, vielseitigste I/O Technologie in einem Notebook.
Stell dir vor, du könntest auf deinem Notebook auf mehrere unkomprimierte HD Videostreams zugreifen - und zwar so schnell, dass du einen HD Spielfilm in Echtzeit schneiden kannst. Thunderbolt macht genau das möglich. Mit Thunderbolt lassen sich superschnelle Peripheriegeräte der nächsten Generation an die Computer der nächsten Generation anschließen - angefangen beim MacBook Pro. Die Thunderbolt Pipeline ist ultraschnell und ultraflexibel. Sie ist über 12 Mal schneller als FireWire 800 und bis zu 20 Mal schneller als USB 2.0. Und sie bietet beispiellose Erweiterungsmöglichkeiten. Kurzum: Sie verändert alles, was du auf deinem Notebook machen kannst.
 
Der Thunderbolt Anschluss gibt dir Plug&Play Anschluss für eine völlig neue Welt von Thunderbolt Peripheriegeräten sowie für das Apple LED Cinema Display und andere Mini DisplayPort Peripheriegeräte. Du kannst bis zu sechs Thunderbolt Geräte in Reihenschaltung anschließen, darunter auch dein Display. Außerdem unterstützt Thunderbolt Video und Achtkanal-Audio, sodass es auch möglich ist, HDMI-kompatible Geräte wie Fernseher oder Stereoanlagen über einen HDMI-Adapter anzuschließen. Auch aktuelle VGA-, DVI- und DisplayPort Adapter werden unterstützt.
 
Die neue FaceTime HD Kamera. Der Unterschied ist ganz klar.
Sieh mehr von deinen Freunden mit dem HD Widescreenformat - und zwar gestochen scharf. Die neue FaceTime HD Kamera bietet die dreifache Auflösung der vorherigen Kamera, was perfekt für das brillante Display mit LED-Hintergrundbeleuchtung ist. Außerdem arbeitet sie jetzt bei schwachem Licht noch besser. Du kannst mit deinen Freunden HD Telefonate in 720p von einem neuen MacBook Pro zu einem anderen führen. Außerdem sind auch Videotelefonate zu anderen Macs mit Intel Prozessor5, zum iPhone 4 oder zum neuen iPod touch möglich.
 
Multi-Touch Trackpad. Fürs tägliche Handwerk.
Mit dem Multi-Touch Trackpad interagierst du auf ganz natürliche Art mit den Inhalten auf deinem Display. Und die glatte Glasoberfläche bietet jede Menge Platz für Gesten. Durch Auf- und Zuziehen kannst du ein- und auszoomen, durch Streichen in deinen Fotos blättern, durch Drehen ein Bild anpassen und vieles mehr. Das Trackpad kommt ohne Taste aus, sodass du überall klicken kannst. Wenn du aus der Welt des rechten Mausklicks kommst, kannst du diesen entweder mit zwei Fingern auslösen, oder du konfigurierst einen physischen Rechtsklick-Bereich auf dem Trackpad. Je mehr du mit dem Multi-Touch Trackpad vertraut bist, desto mehr wirst du dich fragen, wie du jemals ohne ausgekommen bist.
 
Lange Laufzeit. Weniger aufladen. Mehr machen.
Das neue MacBook Pro bietet eine fantastische Batterielaufzeit und das mit leistungsstärkeren Prozessoren und schnelleren Grafikprozessoren. Die energieeffiziente Prozessorarchitektur mit integriertem Video-Encoder sowie das automatische Umschalten zwischen den Grafikprozessoren bei den 15"" und 17"" Modellen helfen, die Batterielaufzeit weiter zu verbessern. So kannst du pro Ladung bis zu 7 Stunden ohne Kabel im Web surfen6 oder es für Liveauftritte oder auf ein Shooting mitnehmen. Die fortschrittlichen chemischen Eigenschaften und die Adaptive Charging Technologie sorgen dafür, dass die Batterie bis zu 1000 Ladezyklen durchlaufen kann.7 Und da die Batterie des MacBook Pro bis zu fünf Jahre hält, kommt das MacBook Pro in einem Zeitraum, in dem ein herkömmliches Notebook drei Batterien verbraucht, mit nur einer aus. Das ist für die Benutzer genauso gut, wie für die Umwelt.
 
Apple verwendet eine neue, strengere Testmethode, um zu messen, welche Ergebnisse du unter realen Bedingungen erzielst, z. B. beim Surfen in einem Café oder wenn du die neuesten Webvideos ansiehst. Und wie schneidet dieses MacBook Pro dabei verglichen mit der Vorgängergeneration ab? Es liefert die gleiche fantastische Leistung.
 
Hat beste Verbindungen.
Unterwegs hast du mit der 802.11n Technologie im MacBook Pro immer Verbindung.8 Das MacBook Pro findet automatisch verfügbare Netzwerke und du kannst dich mit einem Klick verbinden. Auch die drahtlose Bluetooth Technologie ist integriert, sodass du drahtloses Zubehör sofort nach dem Auspacken verwenden kannst.
 
Immer Anschluss finden.
Mit dem neuen Thunderbolt Anschluss kannst du bis zu sechs Geräte in Reihenschaltung anschließen, darunter auch dein Display. So bekommst du eine vollwertige Workstation. Für die Anbindung von iPad, iPod, iPhone, Digitalkameras und externen Festplatten gibt es zwei USB 2.0 Anschlüsse (drei beim 17"" MacBook Pro) und einen FireWire 800 Anschluss.
 
Der neue SDXC Kartensteckplatz der 13"" und 15"" MacBook Pro Modelle unterstützt bis zu 64 GB Karten und macht es leicht, alle deine Fotos auf und von deinem MacBook Pro zu übertragen, damit du sie sofort bearbeiten und teilen kannst. Und der ExpressCard/34 Steckplatz am 17"" MacBook Pro ist perfekt für einen eSATA Adapter geeignet oder sogar für eine 3G Karte für die drahtlose Kommunikation, wenn kein Wi-Fi Netzwerk vorhanden ist.
 
DVDs superschnell brennen.
Homevideos, die du mit iMovie und iDVD gemacht hast, kannst du mit dem 8-fach SuperDrive Laufwerk des MacBook Pro superschnell auf eine DVD brennen. Das SuperDrive kann auch Double-Layer-DVDs (also DVDs mit fast 9 GB Speicherplatz) beschreiben, sodass es auch hervorragend für Datensicherungen geeignet ist.
";2;False;0;;;Apple MacBook Pro MD313D/A 13,3 Zoll Notebook;apple-macbook-pro-md313da-133-zoll-notebook-2;True;True;PD-01095;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;1099.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;41389,3991782407;5;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000456-apple-macbook-pro-md313da-133-zoll-notebook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000457-apple-macbook-pro-md313da-133-zoll-notebook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000458-apple-macbook-pro-md313da-133-zoll-notebook.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Apple MacBook Pro MC721D/A 15,4 Zoll Notebook;3 GB, 16 Zoll, 350 GB, AMD, 4;"
Apple MacBook Pro MC721D/A
Intel Core i7 2635QM, 2 GHz

Unibody-Gehäuse. Am Anfang jedes MacBook Pro steht ein Werkstück aus Aluminium.Stark, leicht und schön in einem.
Das MacBook Pro ist aus einem einzigen Aluminiumblock gefertigt - eine technische Meisterleistung, bei der viele Bauteile durch ein einziges ersetzt werden. Das Ganze nennt sich Unibody. Gleich beim ersten Mal, wenn Sie ein MacBook Pro in der Hand haben, werden Sie den Unterschied spüren. Das Gehäuse ist dünner und leichter als andere Notebooks. Es sieht elegant aus. Und es fühlt sich stabil und robust an: perfekt für die Aktentasche, den Rucksack und natürlich auch für draußen.
 
Ein Display voll brillanter Ideen.
Alles, was Apple Designer und Ingenieure tun, ist von A bis Z durchdacht. Sie entschieden sich beim MacBook Pro für die LED-Hintergrundbeleuchtung, weil das Display damit sofort seine volle Helligkeit erreicht und trotzdem unglaublich dünn ist. Sie verwendeten eine durchgehende Oberfläche aus Glas, nicht nur weil es schön aussieht, sondern weil es dem ganzen Display Struktur verleiht. Und über dem Bildschirm haben sie die neue, integrierte FaceTime HD Kamera versteckt. So siehst du Freunde und Familie im Großformat - und dabei so gut wie nichts von der Kamera.
 
Magnetverschluss
Da der magnetische Verschluss keine beweglichen Teile hat, die abbrechen können oder an denen man hängen bleibt, ist das Öffnen und Schließen so einfach wie alles beim MacBook Pro.
 
Einfach auf alle Anschlüsse zugreifen.
Alle Anschlüsse am MacBook Pro - der MagSafe Netzanschluss, der Gigabit Ethernetanschluss, der Thunderbolt Anschluss, der USB Anschluss, der Karten-Steckplatz und der Audioeingang und -ausgang - sind ganz auf einer Seite des Notebooks integriert. So bleiben die Kabel schön geordnet und Geräte lassen sich schnell und einfach anschließen und auch wieder trennen.
 
Hinterlässt Eindruck. Aber nicht auf die Umwelt.
Weil Apple die vollständige Kontrolle über Design, Fertigung und Verpackung des MacBook Pro hat, hat Apple einen Vorsprung beim Umweltschutz. Die Technologie zur Hintergrundbeleuchtung des Displays spart Energie. Glas und Aluminium sind besonders recyclingfähig. Das MacBook Pro kommt fast ohne Giftstoffe aus. Und die Verpackung des 39,11 cm / 15,4"" Modells ist im Vergleich zum Vorgängermodell 34 Prozent kleiner. Das bedeutet nicht nur, dass für die Verpackungen weniger Bäume gefällt werden, es werden für den Transport auch weniger Flugzeugen, Güterzügen und LKWs benötigt.
 
Thunderbolt AnschlussDie Grafikleistung, die Sie brauchen, wenn Sie sie brauchen.
Alle MacBook Pro Modelle haben jetzt einen integrierten Intel HD Graphics 3000 Prozessor für die täglichen Aufgaben. Er codiert Videos schnell, ermöglicht HD Videotelefonate mit FaceTime und vieles mehr. Und auch Decodieren erledigt er effizienter, was bedeutet, dass Sie richtig lange DVDs und iTunes Filme schauen können. Bei anspruchsvollen Grafikprogrammen wechseln die 39,11 cm / 15,4"" MacBook Pro Modelle automatisch den Grafikprozessor und arbeiten mit den neuen leistungsstarken AMD Radeon Grafikprozessoren. Diese bieten verglichen mit den Vorgängermodellen die bis zu 3-fache Leistung. So sehen Sie bei 3D Spielen mehr Bilder pro Sekunde oder können schneller als je zuvor an HD Videoprojekten arbeiten.
 
Das neue Thunderbolt. Die schnellste, vielseitigste I/O Technologie in einem Notebook.
Stellen Sie sich vor, Sie könnten auf deinem Notebook auf mehrere unkomprimierte HD Videostreams zugreifen - und zwar so schnell, dass Sie einen HD Spielfilm in Echtzeit schneiden können. Thunderbolt macht genau das möglich. Mit Thunderbolt lassen sich superschnelle Peripheriegeräte der nächsten Generation an die Computer der nächsten Generation anschließen - angefangen beim MacBook Pro. Die Thunderbolt Pipeline ist ultraschnell und ultraflexibel. Sie ist über 12 Mal schneller als FireWire 800 und bis zu 20 Mal schneller als USB 2.0. Und sie bietet beispiellose Erweiterungsmöglichkeiten. Kurzum: Sie verändert alles, was Sie auf Ihrem Notebook machen können. Der Thunderbolt Anschluss gibt Ihnen Plug&Play Anschluss für eine völlig neue Welt von Thunderbolt Peripheriegeräten sowie für das Apple LED Cinema Display und andere Mini DisplayPort Peripheriegeräte. Sie können bis zu sechs Thunderbolt Geräte in Reihenschaltung anschließen, darunter auch Ihr Display. Außerdem unterstützt Thunderbolt Video und Achtkanal-Audio, sodass es auch möglich ist, HDMI-kompatible Geräte wie Fernseher oder Stereoanlagen über einen HDMI-Adapter anzuschließen. Auch aktuelle VGA-, DVI- und DisplayPort Adapter werden unterstützt.
 
Die neue FaceTime HD Kamera. Der Unterschied ist ganz klar.
Sehen Sie mehr von Ihren Freunden mit dem HD Widescreenformat - und zwar gestochen scharf. Die neue FaceTime HD Kamera bietet die dreifache Auflösung der vorherigen Kamera, was perfekt für das brillante Display mit LED-Hintergrundbeleuchtung ist. Außerdem arbeitet sie jetzt bei schwachem Licht noch besser. Sie können mit Ihren Freunden HD Telefonate in 720p von einem neuen MacBook Pro zu einem anderen führen. Außerdem sind auch Videotelefonate zu anderen Macs mit Intel Prozessor, zum iPhone 4 oder zum neuen iPod touch möglich.
 
Multi-Touch Trackpad - Jede Menge Platz für GestenMulti-Touch Trackpad. Fürs tägliche Handwerk.
Mit dem Multi-Touch Trackpad interagieren Sie auf ganz natürliche Art mit den Inhalten auf deinem Display. Und die glatte Glasoberfläche bietet jede Menge Platz für Gesten. Durch Auf- und Zuziehen können Sie ein- und auszoomen, durch Streichen in deinen Fotos blättern, durch Drehen ein Bild anpassen und vieles mehr. Das Trackpad kommt ohne Taste aus, sodass Sie überall klicken können. Wenn Sie aus der Welt des rechten Mausklicks kommen, können Sie diesen entweder mit zwei Fingern auslösen, oder Sie konfigurieren einen physischen Rechtsklick-Bereich auf dem Trackpad. Je mehr Sie mit dem Multi-Touch Trackpad vertraut sind, desto mehr werden Sie sich fragen, wie Sie jemals ohne ausgekommen sind.
 
Lange Laufzeit. Weniger aufladen. Mehr machen.
Das neue MacBook Pro bietet eine fantastische Batterielaufzeit und das mit leistungsstärkeren Prozessoren und schnelleren Grafikprozessoren. Die energieeffiziente Prozessorarchitektur mit integriertem Video-Encoder sowie das automatische Umschalten zwischen den Grafikprozessoren bei den 39,11 cm / 15,4"" Modellen helfen, die Batterielaufzeit weiter zu verbessern. So können Sie pro Ladung bis zu 7 Stunden ohne Kabel im Web surfen oder es für Liveauftritte oder auf ein Shooting mitnehmen. Die fortschrittlichen chemischen Eigenschaften und die Adaptive Charging Technologie sorgen dafür, dass die Batterie bis zu 1000 Ladezyklen durchlaufen kann. Und da die Batterie des MacBook Pro bis zu fünf Jahre hält, kommt das MacBook Pro in einem Zeitraum, in dem ein herkömmliches Notebook drei Batterien verbraucht, mit nur einer aus. Das ist für die Benutzer genauso gut, wie für die Umwelt. Apple verwendet eine neue, strengere Testmethode, um zu messen, welche Ergebnisse Sie unter realen Bedingungen erzielen, z. B. beim Surfen in einem Cafe oder wenn Sie die neuesten Webvideos ansehen. Und wie schneidet dieses MacBook Pro dabei verglichen mit der Vorgängergeneration ab? Es liefert die gleiche fantastische Leistung.
 
Hat beste Verbindungen.
Unterwegs haben Sie mit der 802.11n Technologie im MacBook Pro immer Verbindung. Das MacBook Pro findet automatisch verfügbare Netzwerke und Sie können sich mit einem Klick verbinden. Auch die drahtlose Bluetooth Technologie ist integriert, sodass Sie drahtloses Zubehör sofort nach dem Auspacken verwenden können.
 
DVDs superschnell brennen.
Homevideos, die Sie mit iMovie und iDVD gemacht haben, können Sie mit dem 8-fach SuperDrive Laufwerk des MacBook Pro superschnell auf eine DVD brennen. Das SuperDrive kann auch Double-Layer-DVDs (also DVDs mit fast 9 GB Speicherplatz) beschreiben, sodass es auch hervorragend für Datensicherungen geeignet ist.
 
Neue Intel Core i7 Prozessoren.
Neue Quad-Core Intel Core i7 Prozessoren sind Standard beim 39,11 cm / 15,4"" MacBook Pro. Alle Modelle verwenden die kürzlich optimierten Chipsets von Intel. Was heißt das für die neuen MacBook Pro Modelle? Kurz gesagt: Sie sind bis zu zwei Mal schneller als die Vorgängergeneration und erledigen auch anspruchsvolle Aufgaben wie HD Videoschnitt, Audiokompilierung oder Rendering mehrschichtiger Bilddateien unglaublich schnell. Und da Mac OS X Snow Leopard darauf ausgelegt ist, jeden Prozessorkern zu nutzen, holt das Betriebssystem wirklich alles an Leistung aus dem Prozessor heraus.
 
Schnellere Einzelchip-Mikroarchitektur.
Ob Sie einen Film ansehen, Ihren Blog auf den neuesten Stand bringen oder Fotos bearbeiten - die Daten müssen von A nach B gelangen, um verarbeitet werden zu können. Die neueste Intel Core Architektur bringt den Prozessor, den Cache, den Speichercontroller und den Grafikprozessor auf einem einzigen Chip unter. Deswegen müssen die Daten keine weiten Wege zurücklegen, was für Sie schnellere Performance und höhere Effizienz bedeutet.
 
Turbo Boost 2.0.
Angenommen, Sie arbeiten mit einem prozessorintensiven Programm wie Aperture 3 oder Final Cut Pro, das von einem Leistungsschub profitiert würde. Turbo Boost ist eine dynamische Technologie, die automatisch die Geschwindigkeit der aktiven Prozessorkerne auf 3,4 GHz erhöht. Turbo Boost 2.0 ist noch dynamischer und effizienter. Es wechselt die Kernfrequenz in kleineren Schritten als bisher, sodass der Prozessor die Leistung ohne Effizienzeinbußen verwalten kann. All das passiert im Hintergrund. Sie arbeiten einfach nur schneller.
 
Hyper-Threading.
Hyper-Threading ist jetzt Standard auf jedem MacBook Pro. Mit dieser Technologie können auf jedem Kern zwei Threads gleichzeitig laufen, Mac OS X erkennt also bei einem Quad-Core Prozessor acht und bei einem Dual-Core Prozessor vier virtuelle Kerne. Wenn Sie mehrere Programme gleichzeitig verwenden, verteilt der Prozessor die Aufgaben gleichmäßiger über eine größere Anzahl Kerne.
 
Integrierter Speichercontroller.
Mit schnellerem Speicherzugriff legt jeder Kern direkt mit der Verarbeitung der Daten los, statt auf ihr Eintreffen zu warten. Genau deshalb nutzt die neue Intel Core Architektur einen integrierten Speichercontroller, der den schnellen 1333 MHz Speicher direkt mit dem Prozessor verbindet und Ihre Programme immer die maximale Prozessorleistung zur Verfügung haben.
 
Energieeffiziente Grafik.
Dank der neuen Mikroarchitektur ist der Grafikprozessor auf dem gleichen Chip wie der Zentralprozessor und hat direkten Zugriff auf den L3-Cache. Kurze Wege bedeuten mehr Leistung. Der Grafikprozessor erhöht auch automatisch die Taktrate für noch höhere Auslastung. Ein integrierter Video-Encoder ermöglicht jetzt HD Videotelefonate mit FaceTime, und der effiziente Decoder sorgt für lange Batterielaufzeit, wenn Sie sich DVDs oder iTunes Filme ansiehen.
 
Mac OS X. Das fortschrittlichste Betriebssystem der Welt.
Mac OS X ist das Herz jedes MacBook Pro und Mac. Dieses Betriebssystem ist genau auf die integrierten Intel Multicore-Prozessoren und fortschrittlichen Grafikprozessoren zugeschnitten. Die neueste Version, Mac OS X Snow Leopard, basiert komplett auf einer 64-Bit-Architektur, genau wie alle anderen Programme, die mit dem Mac kommen. Das bedeutet: Alles, was Sie auf Ihrem MacBook Pro machen, passiert superschnell und mit einer unglaublichen Gesamtleistung.
 
Hat eine ganze Menge draufProgramme, ebenso leistungsstark wie benutzerfreundlich.
Weil Apple sowohl das MacBook Pro, wie auch die integrierte Software entwickelt, arbeitet alles perfekt zusammen. Und mit den Apple Programmen sind Sie ganz schnell vertraut, weil alle ähnlich funktionieren. Das heißt, wenn Sie ein Programm kennen, sind Sie auch schnell mit allen anderen vertraut. Außerdem weiß Apple genau, was mobile Produktivität bedeutet. Darum haben wir Funktionen wie Expose und Spaces hinzugefügt. Damit können Sie ganz einfach auf alles auf Ihrem MacBook Pro zugreifen. Expose zeigt sämtliche geöffneten Fenster nebeneinander, verkleinert sie und ordnet sie so, dass Sie den Inhalt jedes Fensters sehen können - ein Tastendruck oder eine Geste genügt. Und mit Spaces können Sie Fenster zusammen auf ihrem eigenen Schreibtisch oder Bereich gruppieren und ganz einfach zwischen diesen wechseln. Legen Sie einen Bereich zum Arbeiten fest, einen zum Spielen und einen für was auch immer. Mit Expose und Spaces haben Sie beim Multitasking auf einem Notebookdisplay einen riesigen Vorteil.
 
Darauf verzichten Sie beim Mac: PC-Viren.
Trojaner, Würmer, E-Mail Viren. Die digitale Welt kann ganz schön beängstigend sein. Zum Glück ist der Mac immun gegen die tausenden von Viren, die Windows Computer plagen. Denn Mac OS X kommt mit integrierten Sicherheitsmechanismen, die Sie schützen - ohne dass Sie etwas machen müssen. Und sollten doch mal potenzielle Sicherheitsrisiken auftreten, reagiert Apple sofort und stellt neue Softwareaktualisierungen und Sicherheitsverbesserungen bereit, die Sie automatisch laden und mit einem Klick installieren können.
 
Das automatische Backup rettet Ihren Tag. Und die Woche, den Monat ...
Backups müssen sein. Trotzdem vergissen Sie sie bestimmt hin und wieder. Deshalb kümmert sich jetzt das MacBook Pro um die Datensicherung. Time Machine, ein Programm, das auf jedem Mac dabei ist, sichert automatisch Ihr ganzes System auf einer externen Festplatte oder Time Capsule. Time Machine speichert eine Kopie von jeder Datei. Und es merkt sich, wie Ihr System an einem bestimmten Tag ausgesehen hat. So können Sie, wenn Sie wollen, die Zeit zurückdrehen und Ihren Mac wie in der Vergangenheit sehen.
 
Mit iMovie können Sie aus Ihren Videos großartige Filme machenAuch die täglichen Sachen machen mehr Spaß.
Anders als viele PC-Notebooks kommt das MacBook Pro mit allem, was Sie brauchen, um E-Mails zu senden, Kalender zu verwalten, Kontakte zu organisieren und mehr. Und Sie können schon wenige Minuten nach dem Auspacken damit loslegen. Denn jeder Mac kommt mit Mail, um E-Mails zu senden und empfangen, iCal zum Organisieren von Terminen und wichtigen Ereignissen, dem Adressbuch zum Verwalten von Kontakten, iTunes für alles, was mit Unterhaltung zu tun hat, und weiteren tollen und nützlichen Programmen, die Sie jeden Tag verwenden werden.
 
Der Mac App Store. Tausend weitere Gründe, den Mac zu lieben.
Über tausend Mac Apps sind nur einen Klick entfernt - im Mac App Store. Suchen Sie einfach Apps, die Ihnen gefallen, und klicken Sie einfach, um sie zu laden und zu installieren. Ohne Verpackung. Ohne CDs oder DVDs. Und ohne Probleme. Sie können die Apps nach Kategorien durchstöbern oder direkt etwas Bestimmtes suchen. Und Sie können einfach dafür sorgen, dass Ihre Apps up-to-date sind, denn Ihr Mac zeigt Ihnen an, wann Updates verfügbar sind.
 
iPhoto. Fotos ganz einfach verwalten, bearbeiten und teilen.
iPhoto ist ein benutzerfreundliches Programm für Fotos, mit dem Sie Ihre Bilder schnell organisieren, wiederfinden und verbessern können - sodass sie immer perfekt aussehen. Mit den iPhoto Funktionen ""Gesichter"", ""Orte"" und ""Ereignisse"" behalten Sie den Überblick über Ihre Fotos. Sie sagen Ihnen, wen Sie fotografiert haben, wo und wann. Und all das in den neuen Vollbildmodi.
 
iMovie. Und aus Homevideos werden Home-Blockbuster.
Homevideos müssen nicht langweilig sein. Mit iMovie können Sie aus Ihren Videos großartige Filme machen. Zum Beispiel Trailer im Hollywoodstil, mit denen Sie Ihr Publikum begeistern.
 
GarageBand. Großartige Musik machen, ganz einfachissimo.
Egal, ob Sie Musiktalent haben oder einfach nur neugierig sind - GarageBand ist genau das richtige Programm für Sie. Schließ einfach eine elektrische Gitarre oder ein USB Keyboard an. Und schon können Sie mit virtuellen Nachbildungen der bekanntesten Amps und Stompboxes der Welt sowie mit 100 Software-Instrumenten spielen.
";2;False;0;;;Apple MacBook Pro MC721D/A 15,4 Zoll Notebook;apple-macbook-pro-mc721da-154-zoll-notebook-2;True;True;PD-01093;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;1483.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;41389,3991666667;5;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000545-apple-macbook-pro-mc721da-154-zoll-notebook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000546-apple-macbook-pro-mc721da-154-zoll-notebook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000547-apple-macbook-pro-mc721da-154-zoll-notebook.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Apple MacBook Pro MC725D/A 17 Zoll Notebook;4 GB, 17 Zoll, 500 GB, Tantel, 3;"
Apple MacBook Pro MC725D/A
Intel Core i7 2720QM, 2,2 GHz
 
Stark, leicht und schön in einem.
Das MacBook Pro ist aus einem einzigen Aluminiumblock gefertigt - eine technische Meisterleistung, bei der viele Bauteile durch ein einziges ersetzt werden. Das Ganze nennt sich Unibody. Gleich beim ersten Mal, wenn Sie ein MacBook Pro in der Hand haben, werden Sie den Unterschied spüren. Das Gehäuse ist dünner und leichter als andere Notebooks. Es sieht elegant aus. Und es fühlt sich stabil und robust an: perfekt für die Aktentasche, den Rucksack und natürlich auch für draußen.
 
Ein Display voll brillanter Ideen.
Alles, was Apple Designer und Ingenieure tun, ist von A bis Z durchdacht. Sie entschieden sich beim MacBook Pro für die LED-Hintergrundbeleuchtung, weil das Display damit sofort seine volle Helligkeit erreicht und trotzdem unglaublich dünn ist. Sie verwendeten eine durchgehende Oberfläche aus Glas, nicht nur weil es schön aussieht, sondern weil es dem ganzen Display Struktur verleiht. Und über dem Bildschirm haben sie die neue, integrierte FaceTime HD Kamera versteckt. So siehst du Freunde und Familie im Großformat - und dabei so gut wie nichts von der Kamera.
 
Magnetverschluss
Da der magnetische Verschluss keine beweglichen Teile hat, die abbrechen können oder an denen man hängen bleibt, ist das Öffnen und Schließen so einfach wie alles beim MacBook Pro.
 
Einfach auf alle Anschlüsse zugreifen.
Alle Anschlüsse am MacBook Pro - der MagSafe Netzanschluss, der Gigabit Ethernetanschluss, der Thunderbolt Anschluss, der USB Anschluss, der Karten-Steckplatz und der Audioeingang und -ausgang - sind ganz auf einer Seite des Notebooks integriert. So bleiben die Kabel schön geordnet und Geräte lassen sich schnell und einfach anschließen und auch wieder trennen.
 
Hinterlässt Eindruck. Aber nicht auf die Umwelt.
Weil Apple die vollständige Kontrolle über Design, Fertigung und Verpackung des MacBook Pro hat, hat Apple einen Vorsprung beim Umweltschutz. Die Technologie zur Hintergrundbeleuchtung des Displays spart Energie. Glas und Aluminium sind besonders recyclingfähig. Das MacBook Pro kommt fast ohne Giftstoffe aus. Und die Verpackung des 43,18 cm / 17"" Modells ist im Vergleich zum Vorgängermodell 34 Prozent kleiner. Das bedeutet nicht nur, dass für die Verpackungen weniger Bäume gefällt werden, es werden für den Transport auch weniger Flugzeugen, Güterzügen und LKWs benötigt.
 
Thunderbolt AnschlussDie Grafikleistung, die Sie brauchen, wenn Sie sie brauchen.
Alle MacBook Pro Modelle haben jetzt einen integrierten Intel HD Graphics 3000 Prozessor für die täglichen Aufgaben. Er codiert Videos schnell, ermöglicht HD Videotelefonate mit FaceTime und vieles mehr. Und auch Decodieren erledigt er effizienter, was bedeutet, dass Sie richtig lange DVDs und iTunes Filme schauen können. Bei anspruchsvollen Grafikprogrammen wechseln die 43,18 cm / 17"" MacBook Pro Modelle automatisch den Grafikprozessor und arbeiten mit den neuen leistungsstarken AMD Radeon Grafikprozessoren. Diese bieten verglichen mit den Vorgängermodellen die bis zu 3-fache Leistung. So sehen Sie bei 3D Spielen mehr Bilder pro Sekunde oder können schneller als je zuvor an HD Videoprojekten arbeiten.
 
Das neue Thunderbolt. Die schnellste, vielseitigste I/O Technologie in einem Notebook.
Stellen Sie sich vor, Sie könnten auf deinem Notebook auf mehrere unkomprimierte HD Videostreams zugreifen - und zwar so schnell, dass Sie einen HD Spielfilm in Echtzeit schneiden können. Thunderbolt macht genau das möglich. Mit Thunderbolt lassen sich superschnelle Peripheriegeräte der nächsten Generation an die Computer der nächsten Generation anschließen - angefangen beim MacBook Pro. Die Thunderbolt Pipeline ist ultraschnell und ultraflexibel. Sie ist über 12 Mal schneller als FireWire 800 und bis zu 20 Mal schneller als USB 2.0. Und sie bietet beispiellose Erweiterungsmöglichkeiten. Kurzum: Sie verändert alles, was Sie auf Ihrem Notebook machen können. Der Thunderbolt Anschluss gibt Ihnen Plug&Play Anschluss für eine völlig neue Welt von Thunderbolt Peripheriegeräten sowie für das Apple LED Cinema Display und andere Mini DisplayPort Peripheriegeräte. Sie können bis zu sechs Thunderbolt Geräte in Reihenschaltung anschließen, darunter auch Ihr Display. Außerdem unterstützt Thunderbolt Video und Achtkanal-Audio, sodass es auch möglich ist, HDMI-kompatible Geräte wie Fernseher oder Stereoanlagen über einen HDMI-Adapter anzuschließen. Auch aktuelle VGA-, DVI- und DisplayPort Adapter werden unterstützt.
 
Die neue FaceTime HD Kamera. Der Unterschied ist ganz klar.
Sehen Sie mehr von Ihren Freunden mit dem HD Widescreenformat - und zwar gestochen scharf. Die neue FaceTime HD Kamera bietet die dreifache Auflösung der vorherigen Kamera, was perfekt für das brillante Display mit LED-Hintergrundbeleuchtung ist. Außerdem arbeitet sie jetzt bei schwachem Licht noch besser. Sie können mit Ihren Freunden HD Telefonate in 720p von einem neuen MacBook Pro zu einem anderen führen. Außerdem sind auch Videotelefonate zu anderen Macs mit Intel Prozessor, zum iPhone 4 oder zum neuen iPod touch möglich.
 
Multi-Touch Trackpad - Jede Menge Platz für GestenMulti-Touch Trackpad. Fürs tägliche Handwerk.
Mit dem Multi-Touch Trackpad interagieren Sie auf ganz natürliche Art mit den Inhalten auf deinem Display. Und die glatte Glasoberfläche bietet jede Menge Platz für Gesten. Durch Auf- und Zuziehen können Sie ein- und auszoomen, durch Streichen in deinen Fotos blättern, durch Drehen ein Bild anpassen und vieles mehr. Das Trackpad kommt ohne Taste aus, sodass Sie überall klicken können. Wenn Sie aus der Welt des rechten Mausklicks kommen, können Sie diesen entweder mit zwei Fingern auslösen, oder Sie konfigurieren einen physischen Rechtsklick-Bereich auf dem Trackpad. Je mehr Sie mit dem Multi-Touch Trackpad vertraut sind, desto mehr werden Sie sich fragen, wie Sie jemals ohne ausgekommen sind.
 
Lange Laufzeit. Weniger aufladen. Mehr machen.
Das neue MacBook Pro bietet eine fantastische Batterielaufzeit und das mit leistungsstärkeren Prozessoren und schnelleren Grafikprozessoren. Die energieeffiziente Prozessorarchitektur mit integriertem Video-Encoder sowie das automatische Umschalten zwischen den Grafikprozessoren bei den 43,18 cm / 17"" Modellen helfen, die Batterielaufzeit weiter zu verbessern. So können Sie pro Ladung bis zu 7 Stunden ohne Kabel im Web surfen oder es für Liveauftritte oder auf ein Shooting mitnehmen. Die fortschrittlichen chemischen Eigenschaften und die Adaptive Charging Technologie sorgen dafür, dass die Batterie bis zu 1000 Ladezyklen durchlaufen kann. Und da die Batterie des MacBook Pro bis zu fünf Jahre hält, kommt das MacBook Pro in einem Zeitraum, in dem ein herkömmliches Notebook drei Batterien verbraucht, mit nur einer aus. Das ist für die Benutzer genauso gut, wie für die Umwelt. Apple verwendet eine neue, strengere Testmethode, um zu messen, welche Ergebnisse Sie unter realen Bedingungen erzielen, z. B. beim Surfen in einem Cafe oder wenn Sie die neuesten Webvideos ansehen. Und wie schneidet dieses MacBook Pro dabei verglichen mit der Vorgängergeneration ab? Es liefert die gleiche fantastische Leistung.
 
Hat beste Verbindungen.
Unterwegs haben Sie mit der 802.11n Technologie im MacBook Pro immer Verbindung. Das MacBook Pro findet automatisch verfügbare Netzwerke und Sie können sich mit einem Klick verbinden. Auch die drahtlose Bluetooth Technologie ist integriert, sodass Sie drahtloses Zubehör sofort nach dem Auspacken verwenden können.
 
DVDs superschnell brennen.
Homevideos, die Sie mit iMovie und iDVD gemacht haben, können Sie mit dem 8-fach SuperDrive Laufwerk des MacBook Pro superschnell auf eine DVD brennen. Das SuperDrive kann auch Double-Layer-DVDs (also DVDs mit fast 9 GB Speicherplatz) beschreiben, sodass es auch hervorragend für Datensicherungen geeignet ist.
 
Neue Intel Core i7 Prozessoren.
Neue Quad-Core Intel Core i7 Prozessoren sind Standard beim 43,18 cm / 17"" MacBook Pro. Alle Modelle verwenden die kürzlich optimierten Chipsets von Intel. Was heißt das für die neuen MacBook Pro Modelle? Kurz gesagt: Sie sind bis zu zwei Mal schneller als die Vorgängergeneration und erledigen auch anspruchsvolle Aufgaben wie HD Videoschnitt, Audiokompilierung oder Rendering mehrschichtiger Bilddateien unglaublich schnell. Und da Mac OS X Snow Leopard darauf ausgelegt ist, jeden Prozessorkern zu nutzen, holt das Betriebssystem wirklich alles an Leistung aus dem Prozessor heraus.
 
Schnellere Einzelchip-Mikroarchitektur.
Ob Sie einen Film ansehen, Ihren Blog auf den neuesten Stand bringen oder Fotos bearbeiten - die Daten müssen von A nach B gelangen, um verarbeitet werden zu können. Die neueste Intel Core Architektur bringt den Prozessor, den Cache, den Speichercontroller und den Grafikprozessor auf einem einzigen Chip unter. Deswegen müssen die Daten keine weiten Wege zurücklegen, was für Sie schnellere Performance und höhere Effizienz bedeutet.
 
Turbo Boost 2.0.
Angenommen, Sie arbeiten mit einem prozessorintensiven Programm wie Aperture 3 oder Final Cut Pro, das von einem Leistungsschub profitiert würde. Turbo Boost ist eine dynamische Technologie, die automatisch die Geschwindigkeit der aktiven Prozessorkerne auf 3,4 GHz erhöht. Turbo Boost 2.0 ist noch dynamischer und effizienter. Es wechselt die Kernfrequenz in kleineren Schritten als bisher, sodass der Prozessor die Leistung ohne Effizienzeinbußen verwalten kann. All das passiert im Hintergrund. Sie arbeiten einfach nur schneller.
 
Hyper-Threading.
Hyper-Threading ist jetzt Standard auf jedem MacBook Pro. Mit dieser Technologie können auf jedem Kern zwei Threads gleichzeitig laufen, Mac OS X erkennt also bei einem Quad-Core Prozessor acht und bei einem Dual-Core Prozessor vier virtuelle Kerne. Wenn Sie mehrere Programme gleichzeitig verwenden, verteilt der Prozessor die Aufgaben gleichmäßiger über eine größere Anzahl Kerne.
 
Integrierter Speichercontroller.
Mit schnellerem Speicherzugriff legt jeder Kern direkt mit der Verarbeitung der Daten los, statt auf ihr Eintreffen zu warten. Genau deshalb nutzt die neue Intel Core Architektur einen integrierten Speichercontroller, der den schnellen 1333 MHz Speicher direkt mit dem Prozessor verbindet und Ihre Programme immer die maximale Prozessorleistung zur Verfügung haben.
 
Energieeffiziente Grafik.
Dank der neuen Mikroarchitektur ist der Grafikprozessor auf dem gleichen Chip wie der Zentralprozessor und hat direkten Zugriff auf den L3-Cache. Kurze Wege bedeuten mehr Leistung. Der Grafikprozessor erhöht auch automatisch die Taktrate für noch höhere Auslastung. Ein integrierter Video-Encoder ermöglicht jetzt HD Videotelefonate mit FaceTime, und der effiziente Decoder sorgt für lange Batterielaufzeit, wenn Sie sich DVDs oder iTunes Filme ansiehen.
 
Mac OS X. Das fortschrittlichste Betriebssystem der Welt.
Mac OS X ist das Herz jedes MacBook Pro und Mac. Dieses Betriebssystem ist genau auf die integrierten Intel Multicore-Prozessoren und fortschrittlichen Grafikprozessoren zugeschnitten. Die neueste Version, Mac OS X Snow Leopard, basiert komplett auf einer 64-Bit-Architektur, genau wie alle anderen Programme, die mit dem Mac kommen. Das bedeutet: Alles, was Sie auf Ihrem MacBook Pro machen, passiert superschnell und mit einer unglaublichen Gesamtleistung.
 
Hat eine ganze Menge draufProgramme, ebenso leistungsstark wie benutzerfreundlich.
Weil Apple sowohl das MacBook Pro, wie auch die integrierte Software entwickelt, arbeitet alles perfekt zusammen. Und mit den Apple Programmen sind Sie ganz schnell vertraut, weil alle ähnlich funktionieren. Das heißt, wenn Sie ein Programm kennen, sind Sie auch schnell mit allen anderen vertraut. Außerdem weiß Apple genau, was mobile Produktivität bedeutet. Darum haben wir Funktionen wie Expose und Spaces hinzugefügt. Damit können Sie ganz einfach auf alles auf Ihrem MacBook Pro zugreifen. Expose zeigt sämtliche geöffneten Fenster nebeneinander, verkleinert sie und ordnet sie so, dass Sie den Inhalt jedes Fensters sehen können - ein Tastendruck oder eine Geste genügt. Und mit Spaces können Sie Fenster zusammen auf ihrem eigenen Schreibtisch oder Bereich gruppieren und ganz einfach zwischen diesen wechseln. Legen Sie einen Bereich zum Arbeiten fest, einen zum Spielen und einen für was auch immer. Mit Expose und Spaces haben Sie beim Multitasking auf einem Notebookdisplay einen riesigen Vorteil.
 
Darauf verzichten Sie beim Mac: PC-Viren.
Trojaner, Würmer, E-Mail Viren. Die digitale Welt kann ganz schön beängstigend sein. Zum Glück ist der Mac immun gegen die tausenden von Viren, die Windows Computer plagen. Denn Mac OS X kommt mit integrierten Sicherheitsmechanismen, die Sie schützen - ohne dass Sie etwas machen müssen. Und sollten doch mal potenzielle Sicherheitsrisiken auftreten, reagiert Apple sofort und stellt neue Softwareaktualisierungen und Sicherheitsverbesserungen bereit, die Sie automatisch laden und mit einem Klick installieren können.
 
Das automatische Backup rettet Ihren Tag. Und die Woche, den Monat ...
Backups müssen sein. Trotzdem vergissen Sie sie bestimmt hin und wieder. Deshalb kümmert sich jetzt das MacBook Pro um die Datensicherung. Time Machine, ein Programm, das auf jedem Mac dabei ist, sichert automatisch Ihr ganzes System auf einer externen Festplatte oder Time Capsule. Time Machine speichert eine Kopie von jeder Datei. Und es merkt sich, wie Ihr System an einem bestimmten Tag ausgesehen hat. So können Sie, wenn Sie wollen, die Zeit zurückdrehen und Ihren Mac wie in der Vergangenheit sehen.
 
Mit iMovie können Sie aus Ihren Videos großartige Filme machenAuch die täglichen Sachen machen mehr Spaß.
Anders als viele PC-Notebooks kommt das MacBook Pro mit allem, was Sie brauchen, um E-Mails zu senden, Kalender zu verwalten, Kontakte zu organisieren und mehr. Und Sie können schon wenige Minuten nach dem Auspacken damit loslegen. Denn jeder Mac kommt mit Mail, um E-Mails zu senden und empfangen, iCal zum Organisieren von Terminen und wichtigen Ereignissen, dem Adressbuch zum Verwalten von Kontakten, iTunes für alles, was mit Unterhaltung zu tun hat, und weiteren tollen und nützlichen Programmen, die Sie jeden Tag verwenden werden.
 
Der Mac App Store. Tausend weitere Gründe, den Mac zu lieben.
Über tausend Mac Apps sind nur einen Klick entfernt - im Mac App Store. Suchen Sie einfach Apps, die Ihnen gefallen, und klicken Sie einfach, um sie zu laden und zu installieren. Ohne Verpackung. Ohne CDs oder DVDs. Und ohne Probleme. Sie können die Apps nach Kategorien durchstöbern oder direkt etwas Bestimmtes suchen. Und Sie können einfach dafür sorgen, dass Ihre Apps up-to-date sind, denn Ihr Mac zeigt Ihnen an, wann Updates verfügbar sind.
 
iPhoto. Fotos ganz einfach verwalten, bearbeiten und teilen.
iPhoto ist ein benutzerfreundliches Programm für Fotos, mit dem Sie Ihre Bilder schnell organisieren, wiederfinden und verbessern können - sodass sie immer perfekt aussehen. Mit den iPhoto Funktionen ""Gesichter"", ""Orte"" und ""Ereignisse"" behalten Sie den Überblick über Ihre Fotos. Sie sagen Ihnen, wen Sie fotografiert haben, wo und wann. Und all das in den neuen Vollbildmodi.
 
iMovie. Und aus Homevideos werden Home-Blockbuster.
Homevideos müssen nicht langweilig sein. Mit iMovie können Sie aus Ihren Videos großartige Filme machen. Zum Beispiel Trailer im Hollywoodstil, mit denen Sie Ihr Publikum begeistern.
 
GarageBand. Großartige Musik machen, ganz einfachissimo.
Egal, ob Sie Musiktalent haben oder einfach nur neugierig sind - GarageBand ist genau das richtige Programm für Sie. Schließ einfach eine elektrische Gitarre oder ein USB Keyboard an. Und schon können Sie mit virtuellen Nachbildungen der bekanntesten Amps und Stompboxes der Welt sowie mit 100 Software-Instrumenten spielen.  
";2;False;0;;;Apple MacBook Pro MC725D/A 17 Zoll Notebook;apple-macbook-pro-mc725da-17-zoll-notebook-2;True;True;PD-01094;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;2299.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;41389,3991666667;5;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000312-apple-macbook-pro-mc725da-17-zoll-notebook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000313-apple-macbook-pro-mc725da-17-zoll-notebook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000314-apple-macbook-pro-mc725da-17-zoll-notebook.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Asus Eee PC 1001HA 10,1 Zoll Netbook;3 GB, 17 Zoll, 400 GB, AMDl, 3;"
Eee PC™ 1001HA: Klasse Leistung zu unschlagbarem Preis
 
Der Eee PC™ 1001HA unterscheidet sich von seinen großen Brüdern durch Prozessor und Akkukapazität. Ausgestattet mit einem Intel® Atom™ N270 Prozessor, einem 3 Zellen Akku für bis zu 4 Stunden Laufzeit, WLAN 802.11n Standard sowie weiteren Top Merkmalen, überzeugt der Eee PC™ 1001HA zu einem wirklich unschlagbaren Preis.
 
Eee PC™ 1001HA: Funktionalität meets Design
 
Mit dem kompakten Eee PC™ 1001HA trägt ASUS seinem Anspruch, in den Produkten höchste Funktionalität mit formvollendetem Design zu verbinden, ein weiteres Mal Rechnung. So besticht der neue Eee PC™ durch sein elegantes und gleichzeitig unempfindliches Gehäuse, das mit klaren Linien und nach unten schmaler zulaufenden Kanten dem schlanken Design einer Muschel nachempfunden ist. Aber auch das Innenleben der Kleinen kommt ganz groß raus. Als gewohnt kontaktfreudig erweisen sich die Neulinge dank VGA Port für den Anschluss eines Monitors sowie drei USB 2.0 Schnittstellen, um Maus, Tastatur oder Digicam anzuschließen. Wer Bilder direkt von der SD oder MMC Speicherkarte auf den Eee PC™ übertragen möchte, nutzt den integrierten Kartenleser. Für das Speichern der Fotos stehen bei beiden Modellen eine 160 GB S-ATA Festplatte zur Verfügung.. Das Modell basiert auf Microsoft® Windows® XP Home und ist – wie alle Eee Familienmitglieder – ausgesprochen einfach zu bedienen. Das 10 Zoll WSVGA Display mit stromsparender LED-Hintergrundbeleuchtung sowie die große Tastatur, die zu 92% einer Standard Notebooktastatur entspricht, gewähren zusätzlichen Komfort. Für Chats oder Videokonferenzen hat ASUS die Minis zudem mit einer 0.3 Megapixel Web-/Videokamera sowie einem Mikrofon ausgestattet.
 
 
";2;False;0;;;Asus Eee PC 1001HA 10,1 Zoll;asus-eee-pc-1001ha-101-zoll-netbook-2;True;True;PD-01090;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;243.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;41389,3988657407;5;37;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000563-asus-eee-pc-1001ha-101-zoll-netbook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000564-asus-eee-pc-1001ha-101-zoll-netbook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000565-asus-eee-pc-1001ha-101-zoll-netbook.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"HP Compaq Mini 110c-1110sg 10.1 Zoll Netbook ";4 GB, 18 Zoll, 800 GB, Intel, 2;"
HP Compaq Mini 110c-1110sg 10.1 Zoll Netbook
 
Intel Atom N270 1.6GHz, 1GB RAM, 160GB HDD, Intel GMA 950, Win XP Home
 
Leicht und kompakt
Der Compaq Mini 110c wiegt 1,3 kg (mit 6-Zellen-Akku) und ist ca. 5,5 cm hoch – er ist damit sehr kompakt und fällt ins Auge
 
Elegantes Design
Der Compaq Mini 110c glänzt mit einem eleganten Gehäuse im neuem Imprint-Finish ""Unity"", einem Karomuster, das ins Auge fällt.
 
Ständig in Verbindung
Webcam und Mikrofon sind im Compaq Mini integriert und bieten per WLAN und optionalem WWAN zahlreiche Möglichkeiten zur Pflege sozialer Kontakte; Video-Chats und Video-Konferenzen, die bislang nur zuhause möglich waren, können jetzt im Park, im Cafe oder am Flughafen geführt werden
 
Information und Kommunikation auch unterwegs
Mit dem 10,1-Zoll-BrightView-Display, Original Windows® XP Home, der großen Tastatur (92 % der vollen Größe), drei USB-Anschlüssen und einem 5-in-1 Kartenleser sind Informationen, Kommunikation und Unterhaltung im Internet überall bequem zugänglich.
";2;False;0;;;"HP Compaq Mini 110c-1110sg 10.1 Zoll Netbook ";hp-compaq-mini-110c-1110sg-101-zoll-netbook-2;True;True;PD-01091;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;259.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;41389,3988657407;"5;2095";39;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000598-hp-compaq-mini-110c-1110sg-101-zoll-netbook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000599-hp-compaq-mini-110c-1110sg-101-zoll-netbook.jpg;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Samsung NC10 anyNet 10,2 Zoll Netbook;2 GB, 15 Zoll, 400 GB, AMDl, 4;"
Samsung NC10 anyNet10,2"" Netbook

Intel Atom N270 1.6GHz, 1GB RAM, 160GB HDD, Intel GMA 950 XP Home
 
NC10-anyNet: Entwickelt für das ""mobile Leben"". Entwickelt für höchste Ansprüche in innovativem Design. Das ultrakompakte und leichte Gehäuse bietet eine Reihe von praktischen Features, die das mobile Leben vereinfachen. Brillante Technologie angepasst an das rasante und digitale Leben für noch mehr Mobilität.
 
Schlankes Design
Mit einem optimierten 10,2 Zoll Breitbild Display für ein makelloses visuelles Erlebnis, ist das schlanke NC10 lediglich 1,19 cm hoch und passt nahezu in alle Taschen. Das widerstandsfähige Gehäuse bietet ein Maximum an Tragekomfort und Verlässlichkeit sowie hochwertiger Ergonomie und Stil.
 
Videokonferenz
Ob Videokonferenzen oder Live Messaging - die integrierte 1,3 Megapixel Kamera lässt sie noch leichter mit Freunden, Familie und Kollegen in Kontakt bleiben. Die Kamera verbindet die Auflösung und die Bildqualität einer Fotokamera mit der nachhaltig hohen Bildfrequenz einer Videokamera.
 
Robustes Gehäuse, langlebig und verlässlich
Fühlen Sie sich sicher mit dem robusten Protect-o-Edge Gehäuse, das für Langlebigkeit und Verlässlichkeit steht. Eine aufwendige Serie von 54 Qualitätstests, die von schnellen Temperaturwechseln bis zu elektrischen Überspannungen reichen, gewährleistet neue Standards in Punkto Belastbarkeit und Ausdauer.
 
Antibakterielle Tastatur
Die SilverNano Technologie beschichtet die Tastatur mit nano-kleinen Silberionen, die das Überleben und die Neuentstehung von Bakterien verhindern. Innerhalb von 24 Stunden werden 99,9% aller Bakterien abgetötet und es entsteht eine hygienische Arbeitsatmosphäre.
 
Leichtgewicht
Als eines der weltweit leichtesten 10,2 Zoll Mini Notebooks seiner Klasse, mit einem Gewicht von nur 1,45 kg, ist das NC10 voll bepackt mit neuester Technologie und garantiert dabei maximale Mobilität und Leistung.
  
Vollständige Notebook-Tastatur
Die vollständige Notebook-Tastatur bietet optimalen Schreibkomfort. Ergonomisches Design und optimierte Tastenabstände machen das Arbeiten und Kommunizieren angenehmer und ermöglichen schnelleres sowie fehlerloses Schreiben.
 
Voll ausgestattet für einfachen Datenaustausch
Einfacher Datenaustausch dank einer Vielzahl an Anschlussmöglichkeiten, inklusive einem Kartenleser und drei USB-Anschlüssen, so dass Sie problemlos Bilder, Filme und Daten auf und von nahezu allen modernen Kameras, periphären oder audiovisuellen Geräten transferieren können.
";2;False;0;;;;samsung-nc10-anynet-102-zoll-netbook-2;True;True;PD-01092;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;329.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;41389,3988657407;5;5;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000511-samsung-nc10-anynet-102-zoll-netbook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000512-samsung-nc10-anynet-102-zoll-netbook.jpg;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Germot GM 205 Integralhelm Dekor;Der GM 205 ist der Preisgünstige einsteiger Motorradhelm mit kratzfestem Außenvisier.;"
Germot GM 205 Integralhelm
Ideal für Rollerfahrer oder kurze touren
 
klare, getönte und verspiegelte Visiere zu diesem Modell sind in unserem Shop erhältlich!
 
Eigenschaften: klares, kratzfestes Visier mit Verstellraster, einfacher und schneller Visierwechsel, Visier- und Kopfbelüftung, großes Gesichtsfeld, Nasenspoiler, hautfreundliche Innenausstattung, hochwertige Mehrschichtlackierung mit UV-Schutz, Drucktastensteckschloss, ECE 22 05.

Material: ABS/Polycarbonat Mix

Gewicht: 1.400g +/-50g

Größen: XS (53-54) / S (55-56) / M (57-58) / L (59-60) / XL (61-62) / 2XL (63-64)
Größenangabe in Klammer= Kopfumfang in cm.
";2;False;0;GM205, rollerhelm, integralhelm,germot,motorradhelm;Der GM 205 ist der Preisgünstige einsteiger Motorradhelm und Rollerhelm mit kratzfestem Außenvisier.;Germot GM 205 Integralhelm Dekor;germot-gm-205-integralhelm-dekor;True;True;20596;;5000111105392;False;0;False;;False;False;0;False;0;1;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;2;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;79.9000;79.9000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;41129,4577083333;"1;22";1;;;;5;;False;kg;;;;False;False;False;;;;;False;;;;;; -5;0;True;Apple iPod Nano 16 GB 6. Gen. verschiedene Farben;Apple iPod Nano 16 GB 6. Generation verschiedene Farben;"
Der Remix für Ihre Finger
Der iPod nano mit Multi-Touch ist einfach, intuitiv und macht jede Menge Spaß - wie Ihre Musik. Und er ist jetzt noch kleiner, damit Musik bei allem, was Sie machen, eine größere Rolle spielen kann.
 
Musik. Fühlen Sie den Beat
Ihre Greatest Hits. Zum Anfassen
Die besten Dinge im Leben kommen mit Soundtrack. Und genau da glänzt der iPod nano. Mit dem Multi-Touch Display können Sie Ihre Musik ganz neu erleben. Ein Tipp genügt und er spielt, was Sie hören wollen. Stöbern Sie in Ihrer Musik nach Songs, Alben, Interpreten, Wiedergabelisten, Genres oder Komponisten - streichen Sie dazu über den Homescreen. Sie können sogar die Symbole auf dem Homescreen neu ordnen, damit alles so ist, wie Sie es wollen.
 
Das ist ein echter Musikclip
Mit dem neuen integrierten Clip können Sie mit Ihren Lieblingssongs am Ärmel (oder in der Tasche, Jacke oder Hose) wandern, laufen, Rad fahren und abrocken. Und das Cover zum Song, der gerade läuft, passt perfekt auf das Display.
 
Rock around the clock
Die integrierte aufladbare Lithium-Ionen-Batterie sorgt für 24 Stunden Musik nonstop. Wenn Sie sich den 8 GB oder 16 GB iPod nano anklippen, haben Sie genug Songs für den Weg zur Arbeit, fürs Training und mehr.
 
Songs aus dem Finger schütteln
Überlassen Sie alles dem Zufall. Einfach den iPod nano kurz schütteln und er springt zu einem anderen Song aus Ihrer Sammlung. Schütteln ist perfekt, wenn Ihnen gerade nicht nach einer bestimmten Musik ist. Lassen Sie sich einfach überraschen.
 
Genius. Ihr Mixmaster
 
Eingebauter Clip

 
Ihr persönlicher DJ
Angenommen, Sie hören einen Song, der Ihnen gut gefällt, und möchten ähnliche hören. Ein Tipp auf Genius genügt. Genius findet weitere Songs auf Ihrem iPod nano, die gut dazu passen und erstellt eine Genius Wiedergabeliste für Sie. Wenn Sie einen Mix wollen, auf den Sie selbst nie gekommen wären, erstellen Sie einen Genius Mix in iTunes und synchronisieren ihn mit Ihrem iPod nano. Tippen Sie auf das Symbol für Genius Mixe und entdecken Sie Songs, die Sie lange nicht mehr gehört haben, oder Musik, von der Sie gar nicht mehr wussten, dass Sie sie haben.
 
FM Radio. Und Sie haben alles auf dem Sender
Radio nano
Mit dem iPod nano können Sie auf der Radiowelle surfen. Der FM Tuner zeigt Ihnen den Interpreten, Song oder Sender, der gerade läuft. Ein Tipp genügt und Sie sehen die Radiosteuerungen. Streichen Sie über den Tuner, um den Sender zu wechseln, und stellen Sie dann Ihre Lieblingssender per Fingertipp ein.
 
Live-Pause
Wenn Sie Ihre Lieblingssendung im Radio einmal kurz unterbrechen müssen, verpassen Sie dank Live-Pause trotzdem keinen einzigen Beat. Einfach Tippen und Sendung oder Song werden angehalten. Noch mal Tippen und es geht da weiter, wo Sie aufgehört haben. Sie können sogar bis zu 15 Minuten zurückspulen und dann vorspulen, um wieder live dabei zu sein.
 
Fitness. Treffen Sie Ihren neuen Trainer
 
Anklippen und los geht´s
Das neue Design des iPod nano hilft Ihnen fit zu bleiben. Weil er so klein und tragbar ist, ist er auch beim Joggen, Wandern und im Fitnessstudio immer dabei. Klippen Sie ihn an und steuern Sie Ihre Musik mit nur einem Tippen oder Streichen, sodass Sie sich voll auf Ihr Workout konzentrieren können. Ob Laufen, Walken oder der Weg zum Fitnessstudio - für den kleinen iPod nano ist kein Weg zu weit.
 
Schritte zum Fitbleiben
Sie können den iPod nano auch als Schrittzähler verwenden. Er zählt Ihre Schritte und hilft Ihnen beim Erreichen Ihrer Fitnessziele. Einfach anklippen und los geht´s. Sie können eine tägliche Schrittvorgabe festlegen und Ihre Fortschritte sehen, wenn Sie Ihre Daten auf die Nike+ Website laden.
 
Rocken Sie Ihr Training
Ob beim Joggen oder im Fitnessstudio, mit dem Nike + iPod Sport Kit (separat erhältlich) motiviert Sie der iPod nano vom Warm Up bis zum Cool Down. Ziehen Sie Ihre Nike+ Joggingschuhe an und klippen Sie sich den iPod nano an. Sehen Sie wie Sie Kilometer für Kilometer zurücklegen und hören Sie das Sprachfeedback in Echtzeit, während Ihre Songs laufen. Schließen Sie den iPod nano im Fitnessstudio an ein Gerät an, das mit Nike + iPod kompatibel ist. So zeichnet er Ihre Geschwindigkeit, die Dauer und die Laufstrecke auf, während Sie Ihr Training rocken.
 
iTunes. Damit der iPod was zu spielen hat
Alles für gute Unterhaltung
iTunes ist der beste Weg, Ihren iPod nano mit den neuesten Hits, Podcasts, Hörbüchern und vielem mehr zu füllen. Und auch die beste Art, Ihre immer weiter wachsende Sammlung digitaler Medien zu durchstöbern und auf dem Mac oder PC zu organisieren. Alle im iTunes Store gekauften Inhalte und alle von CDs importierten Songs werden in Ihrer Mediathek in iTunes angezeigt. Sie können Ihre eigenen oder Genius Wiedergabelisten erstellen, Genius Mixe auswählen und alles mit Ihrem iPod nano synchronisieren. Und iTunes ist als kostenloser Download verfügbar.
 
Der beste Music Store der Welt
Laden Sie Ihre Lieblingssongs auf Ihren iPod nano. Oder stöbern Sie in über 13 Millionen Songs und finden Sie weitere Hits. Sie können nach dem Namen eines Interpreten, Songs oder Albums suchen und so genau die richtigen Songs finden. Sie suchen neue Musik und brauchen Hilfe? Die Genius Seitenleiste empfiehlt Ihnen neue Musik, die auf Ihren Lieblingssongs basiert. Sie können in jeden Song kostenlos 30 Sekunden reinhören. Und mit einem Klick können Sie einen Song kaufen. Er wird dann sofort geladen. Schneller und einfacher können Sie Ihre digitale Musiksammlung für den iPod nicht zusammenstellen.
 
Bedienungshilfen
Integrierte Bedienungshilfen.
iPod nano kommt mit Bedienungshilfen, die Menschen mit Handicaps helfen Musik, Hörbücher und mehr zu erleben.
 
VoiceOver
Der iPod touch bietet VoiceOver, die weltweit erste Bildschirmlesefunktion, die auf Gesten basiert. Tippen Sie auf das Display und Sie hören eine Beschreibung des Objekts, das Sie gerade berühren. Steuern Sie den iPod nano durch Doppeltippen, Bewegen oder Streichen. Mit den optionalen Apple Earphones mit Fernbedienung und Mikrofon können Sie Ihre Musik steuern, ohne auf das Display zu sehen. VoiceOver nennt Ihnen den Song und Interpreten und spricht auch noch 29 Sprachen.
 
Weiß auf Schwarz
Wenn Sie stärkeren Kontrast möchten, stellen Sie das Display des iPod nano so ein, dass Weiß auf Schwarz angezeigt wird. Sie können diese Funktion in jeder App und auch auf dem Homescreen verwenden.
 
Mono Audio
Wenn Sie nur auf einem Ohr gut hören können, können Sie ""Mono-Audio"" aktivieren, damit die Audioausgabe auf beide Ohrhörer geleitet wird und Sie beide Kanäle mit dem gesunden Ohr hören können.

Produktbeschreibungen
 
Highlights
- Multi-Touch Display
- Genius - dein Mixmaster
- FM Radio
- iTunes
- Integrierte Bedienungshilfen (VoiceOver und Weiß auf Schwarz)
 
Akku
- Akkutyp: Li-Ion
- Akkulaufzeit bis zu 24 Stunden
 
Display
- Farbdisplay
- Bilddiagonale: 3,91 cm
- 1,54- Display
- Auflösung Breite: 240 Pixel
- Auflösung Höhe: 240 Pixel
 
Speicher
- Interner Speicher 8.000 MB
 
Stromversorgung
- USB-Lader
 
Wiedergabeformate Audio
- AAC
- MP3
- WAV
 
Grundeigenschaften
- Breite: 40,9 mm
- Höhe: 37,5 mm
- Tiefe: 8,78 mm
- Gewicht: 21,1 g
- Gewicht: 21,1 g
- Farbe: Dunkelgrau
 
Lieferumfang
- iPod nano
- Apple Earphones
-Dock Connector auf USB Kabel
- Dokumentation und wichtige Produktinformationen
";2;False;0;;;Apple iPod Nano 16 GB 6. Gen. verschiedene Farben;apple-ipod-nano-16-gb-6-gen-verschiedene-farben;True;True;PD-01087;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;179.0000;179.0000;179.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40900,5013078704;49;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000266-apple-ipod-nano-16-gb-6-gen-verschiedene-farben.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000267-apple-ipod-nano-16-gb-6-gen-verschiedene-farben.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000268-apple-ipod-nano-16-gb-6-gen-verschiedene-farben.jpg;1;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Microsoft Windows XP Professional SP3 OEM;"Microsoft Windows XP Professional SP3 OEM ";"

Microsoft Windows XP Professional SP3 OEM

auf jedem PC installierbar-OEM
 
 
Windows XP Professional ist das bewährte Windows-Betriebssystem für Unternehmen und Heimanwender.
Auf der soliden Grundlage von Windows 2000 bietet Windows XP Professional verbesserte Zuverlässigkeit,
Sicherheit, Leistung und Benutzerfreundlichkeit und setzt zugleich neue Maßstäbe in der Datenverarbeitung.
Mit den professionellen Features zur Administration und zur Netzwerkanbindung erweitert
Windows XP Professional den Funktionsumfang von Windows XP Home Edition.
Windows XP Professional basiert auf einer 32-Bit-PC-Architektur und umfasst ein vollständig geschütztes Speichermodell.
 
Dies alles macht Windows XP Professional zur zuverlässigen Version. Die Funktion ""Systemwiederherstellung""
ermöglicht es Benutzern und Systemverwaltern, den Status eines PCs wiederherzustellen, den er vor einem Ausfall hatte,  ohne dass dabei Daten verloren gehen.
Bei der Systemwiederherstellung werden problemlos erkennbare Wiederherstellungspunkte erstellt,
anhand derer Sie das System auf eine bestimmte Uhrzeit wiederherstellen können. 
";2;False;0;;;Microsoft Windows XP Professional SP3 OEM;microsoft-windows-xp-professional-sp3-oem;True;True;P-2960;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;57.9900;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40889,6330208333;"30;80";3;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000181-microsoft-windows-xp-professional-sp3-oem.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000182-microsoft-windows-xp-professional-sp3-oem.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000183-microsoft-windows-xp-professional-sp3-oem.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Windows 7 32 Bit;Windows 7 32 Bit;"
Windows 7  
 
Die umfassendste Edition von Windows 7
Windows 7 Ultimate ist die vielseitigste und leistungsfähigste Edition von Windows 7. Sie kombiniert die bemerkenswerte Benutzerfreundlichkeit der Unterhaltungsfunktionen von Home Premium mit den unternehmensorientierten Funktionen von Professional, wozu auch die Fähigkeit zum Ausführen zahlreicher Windows XP-Produktivitätsprogramme im Windows XP-Modus gehört.
 
Für mehr Sicherheit können Sie Ihre Daten auch mit BitLocker und Bitlocker To Go verschlüsseln. Und zur Erhöhung der Flexibilität können Sie in einer beliebigen von 35 Sprachen arbeiten. Mit Windows 7 Ultimate müssen Sie auf nichts verzichten.
 
Windows 7 vereinfacht alltägliche Aufgaben
 
Desktop
Unter Windows 7 ist es nun einfacher, noch mehr Aufgaben direkt auf dem Desktop zu erledigen: Verbesserte Taskleistenvorschau, größere Symbole, Anheften und kreative Möglichkeiten der Personalisierung.
 
Neue Möglichkeiten, mit Fenstern zu jonglieren
Überwältigt von der Zahl der geöffneten Fenster? Windows 7 bietet drei einfache und dennoch leistungsfähige neue Funktionen, die wie folgt bezeichnet werden: Aero Shake, Aero Peek und Snap. Sie unterstützen Sie dabei, sofort den Weg durch den Desktop zu finden.
 
 
Die verschiedenen Windows 7 Editionen im Vergleich 
 
Spektakuläre neue Hintergrundbilder
Seien wir ehrlich: Wir verbringen jede Menge Zeit damit, auf unsere PCs zu starren. Die Ästhetik sollte daher nicht zu kurz kommen. Darum enthält Windows 7 viele neue Desktophintergründe, so genannte Hintergrundbilder, unter denen sich alle möglichen Motive von beeindruckend bis unterhaltsam befinden. Oder probieren Sie doch einmal die neue Desktopdiashow aus, in der eine wiederkehrende Reihe von Bildern (unserer oder Ihrer) angezeigt wird. Desktop und langweilig? Das ist vorbei.
 
Schauen Sie sich die ""Superleiste"" an
Schon unter Windows 95 hat die Taskleiste als Ausgangspunkt zum Starten von Programmen und Umschalten zwischen Fenstern gedient. Nicht nur die Zeiten, auch die Arbeitsweisen am PC haben sich geändert. Unter Windows 7 wurde die Taskleiste daher komplett neu gestaltet, damit Sie noch mehr Aufgaben erledigen können. Sie ist ansprechender, kann besser angepasst werden und vereinfacht das Multitasking.
 
Heimnetzgruppe
Dank der Heimnetzgruppe brauchen Sie sich keine Gedanken mehr über die Datei- und Druckerfreigabe in einem Heimnetzwerk zu machen. Verbinden Sie mindestens zwei Windows 7-PCs, und schon kann mit der Heimnetzgruppe ganz einfach die automatische Freigabe von Musik, Bildern, Videos und Dokumentbibliotheken für andere Personen im Haus starten. Und das neue Menü ""Freigeben für"" ermöglicht die schnelle Freigabe einzelner Dateien.
 
Machen Sie sich Sorgen um den Datenschutz? Wir auch. Und deshalb ist die Heimnetzgruppe kennwortgeschützt, sodass Sie die volle Kontrolle über den Zugriff haben. Sie entscheiden, welche Dateien freigegeben werden und welche nicht. Außerdem können Sie Ihre Dateien mit Schreibschutz versehen, d. h., der Inhalt kann von anderen angesehen, aber nicht geändert werden. Einer Heimnetzgruppe beizutreten, ist in jeder Edition von Windows 7 möglich. Das Erstellen einer Heimnetzgruppe ist jedoch nur in den Editionen Home Premium, Professional und Ultimate möglich.
 
 
Die verbesserte Taskleiste verschafft mit Hilfe der neuen Vollbild-Vorschaufenster schnellen Überblick 
 
Sprunglisten
Über die in Windows 7 neu eingeführten Sprunglisten gelangen Sie nun direkt zu den Dokumenten, Bildern, Songs oder Websites, die Sie tagtäglich nutzen. Zum Öffnen einer Sprungliste klicken Sie auf der Taskleiste von Windows 7 einfach mit der rechten Maustaste auf ein Programm (Sie sind auch im Startmenü zu finden.).
 
Der Inhalt einer Sprungliste hängt vom Programm ab. In der Sprungliste für Internet Explorer 8 werden häufig besuchte Websites angezeigt. Windows Media Player 12 enthält häufig abgespielte Musiktitel. Fehlt in der Sprungliste ein Favorit? Sie können dort beliebige Dateien ""anheften"". In Sprunglisten werden nicht nur Verknüpfungen zu Dateien angezeigt. Manchmal bieten sie auch Schnellzugriff auf Befehle für Aufgaben wie das Verfassen neuer E-Mail-Nachrichten oder das Wiedergeben von Musik.
 
Snap
Snap bietet eine schnelle neue Möglichkeit, die Größe geöffneter Fenster einfach durch Ziehen an die Bildschirmränder zu ändern. Je nach Rand, also, oben oder unten, rechts oder links, wird das Fenster verbreitert, oder es füllt den ganzen Bildschirm aus. Und Sie können Fenster auch nebeneinander anordnen. Mit Snap wird das Lesen, das Anordnen und das Vergleichen von Fenstern zum Kinderspiel.
 
 
Den Desktop jederzeit im Blick dank transparenter Fenster 
 
Windows Live Essentials
Was ist Windows Live Essentials? Einfach ausgedrückt, handelt es sich um kostenlose Software, die einen Windows 7-PC mit noch mehr tollen Funktionen ausstattet, z. B. für E-Mail, Instant Messaging, Fotobearbeitung und Blogs. Windows Live Windows Live Essentials ist auf der Windows Live-Website verfügbar. Der kostenlose Download enthält folgende Komponenten: Messenger, Fotogalerie, Mail, Writer, Movie Maker, Symbolleiste und Family Safety.
 
Windows Search
Unter Windows 7 finden Sie noch schneller noch mehr Dinge an noch mehr Orten. Sobald Sie im Suchfeld des Startmenüs mit der Eingabe beginnen, wird eine Liste relevanter Dokumente, Bilder, Musiktitel und E-Mails auf dem PC angezeigt. Die Ergebnisse sind nun nach Kategorie gruppiert und enthalten hervorgehobene Stichwörter und Textausschnitte, um die Suche zu vereinfachen.
 
Dateien werden heutzutage nur noch selten an einem Ort abgelegt. Also ist Windows 7 auch darauf ausgelegt, externe Festplatten, Netzwerk-PCs und Bibliotheken zu durchsuchen. Zu viele Suchergebnisse? Sie können die Suche direkt nach Datum, Dateityp und anderen hilfreichen Kategorien eingrenzen.
 
Windows 7 funktioniert Ihren Vorstellungen entsprechend
 
Leistungsverbesserungen
Niemand wartet gerne. Darum ist Windows 7 nun noch schneller und immer bereit, wenn Sie es sind. Zu den wichtigen Leistungsverbesserungen zählen u. a. schneller Wechsel in und aus dem Energiesparmodus, weniger Speicherbedarf und schnelle Erkennung von USB-Geräten:
 
Standbymodus
Windows 7 kann in den Energiesparmodus versetzt und wiederhergestellt werden und die Verbindung mit dem Drahtlosnetzwerk wieder schneller herstellen.
 
 
Sprunglisten ermöglichen schnellen Zugriff auf häufig anstehende Aufgaben 
 
Suchen
Wenn Sie auf der Suche nach Informationen sind, dann möchten Sie nicht lange warten, sondern Antworten bekommen. Unter Windows 7 werden Suchergebnisse schneller angezeigt. Auch das Sortieren und Gruppieren von Suchergebnissen geht viel rascher vonstatten.
 
USB-Geräte
Wenn Sie zum ersten Mal ein tragbares Flashlaufwerk oder ein anderes USB-Gerät anschließen, stellt Windows 7 es innerhalb weniger Sekunden für Sie bereit. Und wenn Sie es bereits zuvor verwendet haben, dann geht es sogar noch schneller.
 
Rationaler und geringere Auslastung
Anders als seine Vorgänger ist Windows 7 darauf ausgelegt, verlangsamende Hintergrunddienste nur dann auszuführen, wenn Sie sie benötigen. Sie verwenden kein Bluetooth-Gerät? Dann bleibt der Bluetooth-Dienst von Windows 7 ausgeschaltet. Windows 7 benötigt auch weniger Arbeitsspeicher als Windows Vista: eine weitere versteckte Optimierung, mit der die Gesamtleistung gesteigert werden kann.
 
64-Bit-Unterstützung
Wenn Sie sich kürzlich nach einem neuen PC umgesehen haben, dann ist Ihnen sicherlich aufgefallen, dass es mehr Computer mit 64-Bit-Prozessoren gibt. Und möglicherweise haben Sie sich gefragt, welche Vorteile sie bieten. Einfach ausgedrückt, kann ein 64-Bit-PC größere Datenmengen verarbeiten als ein 32-Bit-System. Da mehr RAM (4 GB und mehr) verwendet werden kann, kann ein 64-Bit-Computer schneller reagieren, wenn Sie viele Programme gleichzeitig ausführen.
 
Welchen sollen Sie kaufen? Wenn Sie beabsichtigen, viele Programme gleichzeitig geöffnet zu haben oder häufig zwischen Programmen wechseln müssen und auch wenn Sie lediglich sicherstellen möchten, dass Ihr PC die derzeit größeren Speicher nutzen kann, dann ist ein 64-Bit-Computer die richtige Wahl für Sie. Wenn Sie hingegen höchstens zwei Programme gleichzeitig ausführen oder ältere Hardware und Software verwenden, die von einem 64-Bit-PC nicht unterstützt wird, ist ein 32-Bit-System geeignet. Egal, ob Sie sich für ein 32-Bit- oder ein 64-Bit-System entscheiden, Windows 7 ist bereit.
 
 
Die verbesserte Windows Suche liefert Ergebnisse mit mehr Relevanz 
 
Energieverwaltung
Sie haben es satt, dass sich der Akku Ihres Laptops immer dann verabschiedet, wenn Sie ihn dringend benötigen? Unter Windows 7 können Sie die Akkulaufzeit verlängern. Wie? Zunächst einmal ist die Anzahl von unter Windows 7 ausgeführten Hintergrundaktivitäten viel kleiner, d. h., der PC-Prozessor ist weniger stark ausgelastet und damit die Stromaufnahme geringer.
 
Zudem ist die DVD-Wiedergabe stromsparender (praktisch auf langen Flügen), der Bildschirm wird automatisch abgedunkelt, nicht verwendete Ports werden abgeschaltet, und die Anzeige für die Akkulaufzeit ist genauer. Es ist also unwahrscheinlicher, dass Sie plötzlich mit einem leeren Akku dastehen.
 
Windows 7 macht neue Dinge möglich
 
Netzwerk
Mit Windows 7 wird es zum Kinderspiel, auf dem Laptop an jedem beliebigen Ort Netzwerke anzuzeigen und eine Verbindung mit diesen herzustellen. Klicken Sie einfach nur auf das Netzwerksymbol auf der Taskleiste. Mit ""Verfügbare Netzwerke anzeigen"" werden alle Optionen für Drahtlos- und verkabelte Netzwerke aufgerufen: WiFi, mobiles Breitband, DFÜ oder Unternehmens-VPN. Nur noch ein Klick, und schon steht die Verbindung.
 
Windows Media Center
Live-TV anschauen, anhalten und aufnehmen. Musik hören. Mit der Fotosammlung Eindruck schinden. Onlineunterhaltung genießen. Und das vom Sofa im Wohnzimmer aus. Wundert es da noch, dass Media Center von Kritikern als das verborgene Juwel von Windows bezeichnet wird?
 
Unter Windows 7 wurde das Programm sogar noch erweitert: mit neuen, tollen Features (viele auf Ihre Anregung hin) und visuellen Verbesserungen. Windows Media Center ist in den Editionen Home Premium, Professional und Ultimate von Windows 7 enthalten. Zu den wichtigsten Neuerungen zählen u. a.:
 
 
Komponenten wie Dateien oder Drucker gemeinsam im Heimnetzwerk nutzen 
 
Fernsehen total ...
Windows Media Center unterstützt mehr globale TV-Standards und TV-Tuner (z. B. Digitalfernsehen und HD). Zudem können Sie mit dem Programm nun mehr häufig verwendete Audio- und Videoformate wiedergeben, z. B. 3GP, AAC, AVCHD, DivX, MOV und Xvid.
 
... ohne langes Warten
Haben Sie es satt, sich durch Fernsehprogramme oder eine umfangreiche Musikbibliothek zu quälen? Wechseln Sie schneller zu Titeln und Sendungen mit dem neuen Feature für schnelles Blättern.
 
Atemberaubende neue Diashows
Stellen Sie mit der neuen Diashowerstellung ansprechende Fotocollagen (mit Hintergrundmusik) zusammen. Die sind perfekt geeignet für Partys oder Familienfeiern. Und probieren Sie unbedingt den neuen Diashow-Bildschirmschoner aus: Dafür finden Sie keine Worte!
 
Einfachere Medienfreigabe
Schauen Sie sich aufgezeichnete TV-Sendungen, Musiktitel und Videos an, auch wenn diese nicht auf Ihrem PC gespeichert sind. Mit dem neuen Feature Heimnetzgruppe stehen Medien auf jedem PC unter Windows 7 im gesamten Haus zur Verfügung.
 
Neue Minianwendungen, größere Vorschau
Es gibt eine neue Media Center-Minianwendung. Videos im Schnelldurchlauf anschauen. Mehr Titel- und Sendungsdetails. Größere, besser erkennbare Vorschauminiaturansichten. Und das sind noch längst nicht alle Verbesserungen.
 
 
Windows BitLocker verschlüsselt komplette Laufwerke 
 
Windows Touch
Es hat sich ""ausgemaust"": Mit Windows 7 und einem Kontaktbildschirm können Sie einfach nur mit Ihren Fingern die Onlineausgabe der Tageszeitung durchsehen, die Seiten in einem Fotoalbum durchblättern und Dateien und Ordner zufällig anordnen.
 
Eine eingeschränkte Touchtechnologie ist bereits seit Jahren unter Windows verfügbar. Aber unter Windows 7 erobert sie jede Ecke Ihres PC. Das Startmenü und die Taskleiste weisen nun größere, fingerfreundliche Symbole auf. Auch die vertrauten Windows 7-Programme unterstützen die Fingereingabe. In Paint können Sie jetzt sogar mit dem Finger malen!
 
Windows Touch, nur in den Editionen Home Premium, Professional und Ultimate von Windows 7 enthalten, erkennt auch Mehrfingerbewegungen (geeigneten Monitor vorausgesetzt). Sie möchten ein Bild vergrößern? Bewegen Sie Ihre Finger aufeinander zu. Sie möchten einen Rechtsklick ausführen? Berühren Sie das entsprechende Element mit einem Finger, und tippen Sie mit einem anderen Finger auf den Bildschirm.
 
Zusätzliche Profi-Funktionen
 
Windows XP-Modus
Besser geht's nicht: Mit dem neuen Windows XP-Modus können Sie ältere Windows XP-Geschäftsprogramme direkt auf dem Windows 7-Desktop ausführen. Das Feature, das in erster Linie für kleine und mittelständische Unternehmen entwickelt wurde, steht als separater Download zur Verfügung und kann nur in Verbindung mit Windows 7 Professional und Ultimate eingesetzt werden. Der Windows XP-Modus setzt zudem auch eine Virtualisierungssoftware wie Windows Virtual PC voraus. Beides kann kostenlos von der Microsoft-Website heruntergeladen werden.
 
Domänenbeitritt
Nutzen Sie Ihren PC im Büro, oder planen Sie, ihn für die Heimarbeit zu verwenden? Dann müssen Sie ihn ggf. mit einer Domäne verbinden. Eine Domäne ist eine Art Computernetzwerk, das häufig am Arbeitsplatz vorgefunden wird. (Technisch gesehen, handelt es sich um eine Gruppe von Computern, die zentral verwaltet und unter Einhaltung allgemeiner Regeln betrieben wird.)
 
Windows 7 Professional und Ultimate ermöglichen einen schnellen und sicheren Domänenbeitritt. Führen Sie einfach den benutzerfreundlichen Assistenten aus, und geben Sie Ihre Anmeldeinformationen für das Netzwerk ein. Einen kurzen Moment später sind Sie schon drin.
 
BitLocker-Laufwerkverschlüsselung
Wie können Sie zum Schutz Ihrer Daten vor Datenverlust, Diebstahl oder Hackern beitragen? Die Antwort lautet: BitLocker. Das für Windows 7 verbesserte und in der Ultimate Edition verfügbare BitLocker-Feature hilft Ihnen, alles zu schützen, von Dokumenten bis hin zu Kennwörtern, indem das gesamte Laufwerk, auf dem sich Windows und Ihre Daten befinden, verschlüsselt wird. Sobald BitLocker aktiviert ist, wird jede auf dem Laufwerk gespeicherte Datei automatisch verschlüsselt. BitLocker To Go, ein neues Feature von Windows 7, ermöglicht die Sperrung von leicht verlegten tragbaren Speichergeräten wie USB-Flashlaufwerken und externen Festplatten.
 
Features:
 

Inklusive 32- und 64-Bit-Version
Handbuch: mit Installationsanleitung, Schnelleinstieg und Erklärung der wichtigsten Neuerungen von Windows 7.
Installationssupport: telefonischer Support ist enthalten.
Schneller und einfacher zu bedienen
Verbesserte Taskleiste und Vollbild-Vorschaufenster
Sprunglisten für schnellen Zugriff auf die Programme und Dateien
Verbesserter Desktop vereinfacht das Arbeiten mit Fenstern
Verbesserte Windows Suche
Bessere Geräteverwaltung
Automatisches Einrichten von Heimnetzgruppen
Verbesserte Energieverwaltung
Höchste Kompatibilität
Windows Media Center mit optimierter Benutzeroberfläche
Im ganzen Haus auf Musik, Fotos und Videos zugreifen
Immer auf dem neuesten Stand mit Windows Live
Windows Touch für berührungsempfindliche Bildschirme
Location Aware Printing
Domänenunterstützung und Gruppenrichtlinien
Remote Desktop Host
Erweiterte Datensicherung (Netzwerk und Gruppenrichtlinien)
Windows XP Mode
Verschlüsselndes Dateisystem (EFS)
BitLocker & BitLocker To Go
AppLocker
DirectAccess
BranchCache
Mehrsprachige Bedienerführung (MUI)
 
";2;False;0;;;Windows 7 32 Bit;windows-7-32-bit;True;True;P-2980;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;74.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40889,6296990741;"30;80";3;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000393-windows-7-32-bit.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000394-windows-7-32-bit.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000395-windows-7-32-bit.jpg;1;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Windows 7 64 Bit;Windows 7 64 Bit;"
Windows 7  
 
Die umfassendste Edition von Windows 7
Windows 7 Ultimate ist die vielseitigste und leistungsfähigste Edition von Windows 7. Sie kombiniert die bemerkenswerte Benutzerfreundlichkeit der Unterhaltungsfunktionen von Home Premium mit den unternehmensorientierten Funktionen von Professional, wozu auch die Fähigkeit zum Ausführen zahlreicher Windows XP-Produktivitätsprogramme im Windows XP-Modus gehört.
 
Für mehr Sicherheit können Sie Ihre Daten auch mit BitLocker und Bitlocker To Go verschlüsseln. Und zur Erhöhung der Flexibilität können Sie in einer beliebigen von 35 Sprachen arbeiten. Mit Windows 7 Ultimate müssen Sie auf nichts verzichten.
 
Windows 7 vereinfacht alltägliche Aufgaben
 
Desktop
Unter Windows 7 ist es nun einfacher, noch mehr Aufgaben direkt auf dem Desktop zu erledigen: Verbesserte Taskleistenvorschau, größere Symbole, Anheften und kreative Möglichkeiten der Personalisierung.
 
Neue Möglichkeiten, mit Fenstern zu jonglieren
Überwältigt von der Zahl der geöffneten Fenster? Windows 7 bietet drei einfache und dennoch leistungsfähige neue Funktionen, die wie folgt bezeichnet werden: Aero Shake, Aero Peek und Snap. Sie unterstützen Sie dabei, sofort den Weg durch den Desktop zu finden.
 
 
Die verschiedenen Windows 7 Editionen im Vergleich 
 
Spektakuläre neue Hintergrundbilder
Seien wir ehrlich: Wir verbringen jede Menge Zeit damit, auf unsere PCs zu starren. Die Ästhetik sollte daher nicht zu kurz kommen. Darum enthält Windows 7 viele neue Desktophintergründe, so genannte Hintergrundbilder, unter denen sich alle möglichen Motive von beeindruckend bis unterhaltsam befinden. Oder probieren Sie doch einmal die neue Desktopdiashow aus, in der eine wiederkehrende Reihe von Bildern (unserer oder Ihrer) angezeigt wird. Desktop und langweilig? Das ist vorbei.
 
Schauen Sie sich die "Superleiste" an
Schon unter Windows 95 hat die Taskleiste als Ausgangspunkt zum Starten von Programmen und Umschalten zwischen Fenstern gedient. Nicht nur die Zeiten, auch die Arbeitsweisen am PC haben sich geändert. Unter Windows 7 wurde die Taskleiste daher komplett neu gestaltet, damit Sie noch mehr Aufgaben erledigen können. Sie ist ansprechender, kann besser angepasst werden und vereinfacht das Multitasking.
 
Heimnetzgruppe
Dank der Heimnetzgruppe brauchen Sie sich keine Gedanken mehr über die Datei- und Druckerfreigabe in einem Heimnetzwerk zu machen. Verbinden Sie mindestens zwei Windows 7-PCs, und schon kann mit der Heimnetzgruppe ganz einfach die automatische Freigabe von Musik, Bildern, Videos und Dokumentbibliotheken für andere Personen im Haus starten. Und das neue Menü "Freigeben für" ermöglicht die schnelle Freigabe einzelner Dateien.
 
Machen Sie sich Sorgen um den Datenschutz? Wir auch. Und deshalb ist die Heimnetzgruppe kennwortgeschützt, sodass Sie die volle Kontrolle über den Zugriff haben. Sie entscheiden, welche Dateien freigegeben werden und welche nicht. Außerdem können Sie Ihre Dateien mit Schreibschutz versehen, d. h., der Inhalt kann von anderen angesehen, aber nicht geändert werden. Einer Heimnetzgruppe beizutreten, ist in jeder Edition von Windows 7 möglich. Das Erstellen einer Heimnetzgruppe ist jedoch nur in den Editionen Home Premium, Professional und Ultimate möglich.
 
 
Die verbesserte Taskleiste verschafft mit Hilfe der neuen Vollbild-Vorschaufenster schnellen Überblick 
 
Sprunglisten
Über die in Windows 7 neu eingeführten Sprunglisten gelangen Sie nun direkt zu den Dokumenten, Bildern, Songs oder Websites, die Sie tagtäglich nutzen. Zum Öffnen einer Sprungliste klicken Sie auf der Taskleiste von Windows 7 einfach mit der rechten Maustaste auf ein Programm (Sie sind auch im Startmenü zu finden.).
 
Der Inhalt einer Sprungliste hängt vom Programm ab. In der Sprungliste für Internet Explorer 8 werden häufig besuchte Websites angezeigt. Windows Media Player 12 enthält häufig abgespielte Musiktitel. Fehlt in der Sprungliste ein Favorit? Sie können dort beliebige Dateien "anheften". In Sprunglisten werden nicht nur Verknüpfungen zu Dateien angezeigt. Manchmal bieten sie auch Schnellzugriff auf Befehle für Aufgaben wie das Verfassen neuer E-Mail-Nachrichten oder das Wiedergeben von Musik.
 
Snap
Snap bietet eine schnelle neue Möglichkeit, die Größe geöffneter Fenster einfach durch Ziehen an die Bildschirmränder zu ändern. Je nach Rand, also, oben oder unten, rechts oder links, wird das Fenster verbreitert, oder es füllt den ganzen Bildschirm aus. Und Sie können Fenster auch nebeneinander anordnen. Mit Snap wird das Lesen, das Anordnen und das Vergleichen von Fenstern zum Kinderspiel.
 
 
Den Desktop jederzeit im Blick dank transparenter Fenster 
 
Windows Live Essentials
Was ist Windows Live Essentials? Einfach ausgedrückt, handelt es sich um kostenlose Software, die einen Windows 7-PC mit noch mehr tollen Funktionen ausstattet, z. B. für E-Mail, Instant Messaging, Fotobearbeitung und Blogs. Windows Live Windows Live Essentials ist auf der Windows Live-Website verfügbar. Der kostenlose Download enthält folgende Komponenten: Messenger, Fotogalerie, Mail, Writer, Movie Maker, Symbolleiste und Family Safety.
 
Windows Search
Unter Windows 7 finden Sie noch schneller noch mehr Dinge an noch mehr Orten. Sobald Sie im Suchfeld des Startmenüs mit der Eingabe beginnen, wird eine Liste relevanter Dokumente, Bilder, Musiktitel und E-Mails auf dem PC angezeigt. Die Ergebnisse sind nun nach Kategorie gruppiert und enthalten hervorgehobene Stichwörter und Textausschnitte, um die Suche zu vereinfachen.
 
Dateien werden heutzutage nur noch selten an einem Ort abgelegt. Also ist Windows 7 auch darauf ausgelegt, externe Festplatten, Netzwerk-PCs und Bibliotheken zu durchsuchen. Zu viele Suchergebnisse? Sie können die Suche direkt nach Datum, Dateityp und anderen hilfreichen Kategorien eingrenzen.
 
Windows 7 funktioniert Ihren Vorstellungen entsprechend
 
Leistungsverbesserungen
Niemand wartet gerne. Darum ist Windows 7 nun noch schneller und immer bereit, wenn Sie es sind. Zu den wichtigen Leistungsverbesserungen zählen u. a. schneller Wechsel in und aus dem Energiesparmodus, weniger Speicherbedarf und schnelle Erkennung von USB-Geräten:
 
Standbymodus
Windows 7 kann in den Energiesparmodus versetzt und wiederhergestellt werden und die Verbindung mit dem Drahtlosnetzwerk wieder schneller herstellen.
 
 
Sprunglisten ermöglichen schnellen Zugriff auf häufig anstehende Aufgaben 
 
Suchen
Wenn Sie auf der Suche nach Informationen sind, dann möchten Sie nicht lange warten, sondern Antworten bekommen. Unter Windows 7 werden Suchergebnisse schneller angezeigt. Auch das Sortieren und Gruppieren von Suchergebnissen geht viel rascher vonstatten.
 
USB-Geräte
Wenn Sie zum ersten Mal ein tragbares Flashlaufwerk oder ein anderes USB-Gerät anschließen, stellt Windows 7 es innerhalb weniger Sekunden für Sie bereit. Und wenn Sie es bereits zuvor verwendet haben, dann geht es sogar noch schneller.
 
Rationaler und geringere Auslastung
Anders als seine Vorgänger ist Windows 7 darauf ausgelegt, verlangsamende Hintergrunddienste nur dann auszuführen, wenn Sie sie benötigen. Sie verwenden kein Bluetooth-Gerät? Dann bleibt der Bluetooth-Dienst von Windows 7 ausgeschaltet. Windows 7 benötigt auch weniger Arbeitsspeicher als Windows Vista: eine weitere versteckte Optimierung, mit der die Gesamtleistung gesteigert werden kann.
 
64-Bit-Unterstützung
Wenn Sie sich kürzlich nach einem neuen PC umgesehen haben, dann ist Ihnen sicherlich aufgefallen, dass es mehr Computer mit 64-Bit-Prozessoren gibt. Und möglicherweise haben Sie sich gefragt, welche Vorteile sie bieten. Einfach ausgedrückt, kann ein 64-Bit-PC größere Datenmengen verarbeiten als ein 32-Bit-System. Da mehr RAM (4 GB und mehr) verwendet werden kann, kann ein 64-Bit-Computer schneller reagieren, wenn Sie viele Programme gleichzeitig ausführen.
 
Welchen sollen Sie kaufen? Wenn Sie beabsichtigen, viele Programme gleichzeitig geöffnet zu haben oder häufig zwischen Programmen wechseln müssen und auch wenn Sie lediglich sicherstellen möchten, dass Ihr PC die derzeit größeren Speicher nutzen kann, dann ist ein 64-Bit-Computer die richtige Wahl für Sie. Wenn Sie hingegen höchstens zwei Programme gleichzeitig ausführen oder ältere Hardware und Software verwenden, die von einem 64-Bit-PC nicht unterstützt wird, ist ein 32-Bit-System geeignet. Egal, ob Sie sich für ein 32-Bit- oder ein 64-Bit-System entscheiden, Windows 7 ist bereit.
 
 
Die verbesserte Windows Suche liefert Ergebnisse mit mehr Relevanz 
 
Energieverwaltung
Sie haben es satt, dass sich der Akku Ihres Laptops immer dann verabschiedet, wenn Sie ihn dringend benötigen? Unter Windows 7 können Sie die Akkulaufzeit verlängern. Wie? Zunächst einmal ist die Anzahl von unter Windows 7 ausgeführten Hintergrundaktivitäten viel kleiner, d. h., der PC-Prozessor ist weniger stark ausgelastet und damit die Stromaufnahme geringer.
 
Zudem ist die DVD-Wiedergabe stromsparender (praktisch auf langen Flügen), der Bildschirm wird automatisch abgedunkelt, nicht verwendete Ports werden abgeschaltet, und die Anzeige für die Akkulaufzeit ist genauer. Es ist also unwahrscheinlicher, dass Sie plötzlich mit einem leeren Akku dastehen.
 
Windows 7 macht neue Dinge möglich
 
Netzwerk
Mit Windows 7 wird es zum Kinderspiel, auf dem Laptop an jedem beliebigen Ort Netzwerke anzuzeigen und eine Verbindung mit diesen herzustellen. Klicken Sie einfach nur auf das Netzwerksymbol auf der Taskleiste. Mit "Verfügbare Netzwerke anzeigen" werden alle Optionen für Drahtlos- und verkabelte Netzwerke aufgerufen: WiFi, mobiles Breitband, DFÜ oder Unternehmens-VPN. Nur noch ein Klick, und schon steht die Verbindung.
 
Windows Media Center
Live-TV anschauen, anhalten und aufnehmen. Musik hören. Mit der Fotosammlung Eindruck schinden. Onlineunterhaltung genießen. Und das vom Sofa im Wohnzimmer aus. Wundert es da noch, dass Media Center von Kritikern als das verborgene Juwel von Windows bezeichnet wird?
 
Unter Windows 7 wurde das Programm sogar noch erweitert: mit neuen, tollen Features (viele auf Ihre Anregung hin) und visuellen Verbesserungen. Windows Media Center ist in den Editionen Home Premium, Professional und Ultimate von Windows 7 enthalten. Zu den wichtigsten Neuerungen zählen u. a.:
 
 
Komponenten wie Dateien oder Drucker gemeinsam im Heimnetzwerk nutzen 
 
Fernsehen total ...
Windows Media Center unterstützt mehr globale TV-Standards und TV-Tuner (z. B. Digitalfernsehen und HD). Zudem können Sie mit dem Programm nun mehr häufig verwendete Audio- und Videoformate wiedergeben, z. B. 3GP, AAC, AVCHD, DivX, MOV und Xvid.
 
... ohne langes Warten
Haben Sie es satt, sich durch Fernsehprogramme oder eine umfangreiche Musikbibliothek zu quälen? Wechseln Sie schneller zu Titeln und Sendungen mit dem neuen Feature für schnelles Blättern.
 
Atemberaubende neue Diashows
Stellen Sie mit der neuen Diashowerstellung ansprechende Fotocollagen (mit Hintergrundmusik) zusammen. Die sind perfekt geeignet für Partys oder Familienfeiern. Und probieren Sie unbedingt den neuen Diashow-Bildschirmschoner aus: Dafür finden Sie keine Worte!
 
Einfachere Medienfreigabe
Schauen Sie sich aufgezeichnete TV-Sendungen, Musiktitel und Videos an, auch wenn diese nicht auf Ihrem PC gespeichert sind. Mit dem neuen Feature Heimnetzgruppe stehen Medien auf jedem PC unter Windows 7 im gesamten Haus zur Verfügung.
 
Neue Minianwendungen, größere Vorschau
Es gibt eine neue Media Center-Minianwendung. Videos im Schnelldurchlauf anschauen. Mehr Titel- und Sendungsdetails. Größere, besser erkennbare Vorschauminiaturansichten. Und das sind noch längst nicht alle Verbesserungen.
 
 
Windows BitLocker verschlüsselt komplette Laufwerke 
 
Windows Touch
Es hat sich "ausgemaust": Mit Windows 7 und einem Kontaktbildschirm können Sie einfach nur mit Ihren Fingern die Onlineausgabe der Tageszeitung durchsehen, die Seiten in einem Fotoalbum durchblättern und Dateien und Ordner zufällig anordnen.
 
Eine eingeschränkte Touchtechnologie ist bereits seit Jahren unter Windows verfügbar. Aber unter Windows 7 erobert sie jede Ecke Ihres PC. Das Startmenü und die Taskleiste weisen nun größere, fingerfreundliche Symbole auf. Auch die vertrauten Windows 7-Programme unterstützen die Fingereingabe. In Paint können Sie jetzt sogar mit dem Finger malen!
 
Windows Touch, nur in den Editionen Home Premium, Professional und Ultimate von Windows 7 enthalten, erkennt auch Mehrfingerbewegungen (geeigneten Monitor vorausgesetzt). Sie möchten ein Bild vergrößern? Bewegen Sie Ihre Finger aufeinander zu. Sie möchten einen Rechtsklick ausführen? Berühren Sie das entsprechende Element mit einem Finger, und tippen Sie mit einem anderen Finger auf den Bildschirm.
 
Zusätzliche Profi-Funktionen
 
Windows XP-Modus
Besser geht's nicht: Mit dem neuen Windows XP-Modus können Sie ältere Windows XP-Geschäftsprogramme direkt auf dem Windows 7-Desktop ausführen. Das Feature, das in erster Linie für kleine und mittelständische Unternehmen entwickelt wurde, steht als separater Download zur Verfügung und kann nur in Verbindung mit Windows 7 Professional und Ultimate eingesetzt werden. Der Windows XP-Modus setzt zudem auch eine Virtualisierungssoftware wie Windows Virtual PC voraus. Beides kann kostenlos von der Microsoft-Website heruntergeladen werden.
 
Domänenbeitritt
Nutzen Sie Ihren PC im Büro, oder planen Sie, ihn für die Heimarbeit zu verwenden? Dann müssen Sie ihn ggf. mit einer Domäne verbinden. Eine Domäne ist eine Art Computernetzwerk, das häufig am Arbeitsplatz vorgefunden wird. (Technisch gesehen, handelt es sich um eine Gruppe von Computern, die zentral verwaltet und unter Einhaltung allgemeiner Regeln betrieben wird.)
 
Windows 7 Professional und Ultimate ermöglichen einen schnellen und sicheren Domänenbeitritt. Führen Sie einfach den benutzerfreundlichen Assistenten aus, und geben Sie Ihre Anmeldeinformationen für das Netzwerk ein. Einen kurzen Moment später sind Sie schon drin.
 
BitLocker-Laufwerkverschlüsselung
Wie können Sie zum Schutz Ihrer Daten vor Datenverlust, Diebstahl oder Hackern beitragen? Die Antwort lautet: BitLocker. Das für Windows 7 verbesserte und in der Ultimate Edition verfügbare BitLocker-Feature hilft Ihnen, alles zu schützen, von Dokumenten bis hin zu Kennwörtern, indem das gesamte Laufwerk, auf dem sich Windows und Ihre Daten befinden, verschlüsselt wird. Sobald BitLocker aktiviert ist, wird jede auf dem Laufwerk gespeicherte Datei automatisch verschlüsselt. BitLocker To Go, ein neues Feature von Windows 7, ermöglicht die Sperrung von leicht verlegten tragbaren Speichergeräten wie USB-Flashlaufwerken und externen Festplatten.
 
Features:
 

Inklusive 32- und 64-Bit-Version
Handbuch: mit Installationsanleitung, Schnelleinstieg und Erklärung der wichtigsten Neuerungen von Windows 7.
Installationssupport: telefonischer Support ist enthalten.
Schneller und einfacher zu bedienen
Verbesserte Taskleiste und Vollbild-Vorschaufenster
Sprunglisten für schnellen Zugriff auf die Programme und Dateien
Verbesserter Desktop vereinfacht das Arbeiten mit Fenstern
Verbesserte Windows Suche
Bessere Geräteverwaltung
Automatisches Einrichten von Heimnetzgruppen
Verbesserte Energieverwaltung
Höchste Kompatibilität
Windows Media Center mit optimierter Benutzeroberfläche
Im ganzen Haus auf Musik, Fotos und Videos zugreifen
Immer auf dem neuesten Stand mit Windows Live
Windows Touch für berührungsempfindliche Bildschirme
Location Aware Printing
Domänenunterstützung und Gruppenrichtlinien
Remote Desktop Host
Erweiterte Datensicherung (Netzwerk und Gruppenrichtlinien)
Windows XP Mode
Verschlüsselndes Dateisystem (EFS)
BitLocker & BitLocker To Go
AppLocker
DirectAccess
BranchCache
Mehrsprachige Bedienerführung (MUI)
";2;False;0;;;Windows 7 64 Bit;windows-7-64-bit;True;True;P-2990;;;False;0;False;;False;False;0;False;0;1;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;59.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40889,6295138889;"30;80";3;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000393-windows-7-32-bit.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000397-windows-7-32-bit.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000396-windows-7-32-bit.jpg;2;;False;ounce;;;;False;False;False;;;;;False;;;;;; -5;0;True;Toshiba Satellite L775-11K 43,9 cm (17,3 Zoll) Notebook;4 GB, 18 Zoll, 300 GB, Intel, 2;"
Der Satellite L775 bietet Ihnen die perfekte Mischung aus schickem Design und starker Leistung. Hier bekommen Sie nicht nur eine umfangreiche Ausstattung, sondern auch echte High-Definition-Performance. Intel®-Prozessoren der zweiten Generation sorgen für zügiges Arbeiten in all Ihren Anwendungen. Das 43,9 cm (17,3"") TruBrite® HD+ Display mit LED-Hintergrundbeleuchtung liefert in Kombination mit der NVIDIA® ein umwerfendes Bild. Dolby® AdvancedAudio-Technologie und integrierte Onkyo®-Lautsprecher mit guter Klangqualität runden die Multimedia-Ausstattung ab. Dazu noch ein Multitouch-Touchpad, 2und ein attraktives Matrix-Design in der Farbvariante Zinkgrau – bei diesem Notebook bleiben wirklich keine Wünsche offen.
 
Attraktives Design
Modernes Hochglanzgehäuse mit Matrix-Finish in Zinkgrau.
 
Beste Bildqualität
Das riesige 43,9 cm (17,3"") TruBrite® HD+ Display mit LED-Hintergrundbeleuchtung bietet beste High-Definition-Qualität. Eine hoch auflösende Bildwiedergabe wird dadurch selbst bei DVDs möglich.
 
Optimaler Klang
Integrierte Onkyo®-Lautsprecher sorgen in Kombination mit der Dolby® Advanced Audio-Technologie für einen vollen Sound.
 
Ultra schnell
USB 3.0-Technologie ermöglicht für ihre Multimedia-Dateien einen schnelleren Datentransfers als je zuvor.
 
""USB Sleep-and-Charge""-Funktion
Sie können Ihr Handy oder MP3 Player aufladen – und zwar selbst, wenn das Notebook ausgeschaltet ist.
 
Bedienerfreundlich
Touchpad mit Multitouch Gestensteuerung, Touch Pad an/aus Taste, Multi-Kartenleser und Tastatur mit 10er Nummernblock.
 
Entertainment
Kinoerlebnis auf einem externen Fernseher genießen über RGB (VGA) Anschluss oder in High Definition Qualität mit HDMI Anschluss.
 
Umweltfreundlich
Eco Stromsparfunktion, ENERGY STAR 5.0 qualifiziert und ein energieeffizientes Display mit LED Hintergrundbeleuchtung. 
";2;False;0;;;Toshiba Satellite L775-11K 43,9 cm (17,3 Zoll) Notebook;toshiba-satellite-l775-11k-439-cm-173-zoll-notebook;True;True;P-0840;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;539.9000;539.9000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40889,5852777778;5;40;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000590-toshiba-satellite-l775-11k-439-cm-173-zoll-notebook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000591-toshiba-satellite-l775-11k-439-cm-173-zoll-notebook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000592-toshiba-satellite-l775-11k-439-cm-173-zoll-notebook.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Logitech HD Webcam C615 ";"Logitech HD Webcam C615 ";"
Logitech HD Webcam C615
Mit dieser flexibel zusammenklappbaren Webcam führen Sie HD-Videogespräche in 720p und laden Full HD-Videos in 1080p mit nur einem Klick auf Facebook hoch. Inhalte, Ort und Setup wählen Sie.
 
Full HD-Videoaufnahmen in 1080p und HD-Videogespräche in 720p
Zeichnen Sie Ihr Videos in Full HD 1080p und im atemberaubenden Breitbildformat auf. Sie können Videogespräche in 720p mit den meisten Instant Messengern und Logitech Vid™ HD führen.* Dank des eingebauten Autofokus bleiben Ihre Bilder selbst bei Nahaufnahmen (ab einer Entfernung von 10 cm vom Objektiv) gestochen scharf. Machen Sie hochauflösende Schnappschüsse mit bis zu 8 Megapixeln (Software-interpoliert).
 

1-Klick-Upload auf Facebook
Mit nur einem Klick können Sie Full HD-Videoaufnahmen in 1080p-Auflösung erfassen und auf Facebook, Twitter™ oder YouTube® hochladen.
 

Flexibles, tragbares Design
Dank des zusammenklappbaren Designs und des kurzen USB-Kabels ist die Webcam leicht zu transportieren. Das USB-Verlängerungskabel bietet Ihnen bei Bedarf zusätzlichen Spielraum.
 
Drehbares Design mit Stativhalterung
Wenn Sie die Webcam an einem Stativ befestigen, haben Sie noch mehr Stellmöglichkeiten. Dank der 360-Grad-Schwenkfunktion sind Gespräche und Aufnahmen aus jedem Winkel möglich. Das Stativ selbst ist nicht im Lieferumfang enthalten.
 
Kompatibel mit Windows und Mac
Windows? Mac? iChat®? Skype™? Google Voice™ und Chat? Ganz egal. Ihre Webcam funktioniert mit allen. Für die Bearbeitung Ihrer Fotos ist sie außerdem mit iPhoto®, iMovie® und sogar mit Photo Booth® kompatibel.
 

Beinhaltet Logitech Vid™ HD
Jetzt sind HD-Videogespräche kostenlos, schnell und einfach. Die Software wird bei der Einrichtung Ihrer Webcam mitinstalliert. Und Sie können sogar Videonachrichten für Freunde und Familie hinterlassen, wenn diese Ihren Anruf nicht entgegennehmen können.
 
Kostenlose Videobearbeitungssoftware
Logitech und MAGIX machen Ihnen ein besonderes Angebot: Sie erhalten jetzt mit Ihrer neuen Logitech-Webcam auch gleich MAGIX™ Photo Manager 9 und MAGIX™ Video Easy. Und zwar kostenlos.****
 
Anmeldung über Gesichtserkennung
Melden Sie sich bei Ihrem Computer und auf Ihren Lieblings-Internetseiten mit der eingebauten Gesichtserkennungssoftware an. Damit sparen Sie Zeit und imponieren Ihren Freunden.*****
 

* Für Mac® sind HD-Videogespräche mit Logitech Vid™ HD verfügbar. Für HD-Videogespräche mit anderer Software überprüfen Sie bitte die Verfügbarkeit.
** Nicht für Mac verfügbar.
*** Nur für Windows-Computer. Intel® Pentium® 4 (2,8 GHz) empfohlen.
**** E-Mail-Registrierung erforderlich. Es gelten zusätzliche Bestimmungen. Nur für Windows-Computer.
***** 60-Tage-Probeangebot. Es gelten zusätzliche Bestimmungen. Nicht für Mac verfügbar.
";2;False;0;;;"Logitech HD Webcam C615 ";logitech-hd-webcam-c615;True;True;P-2910;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;89.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40889,4833449074;27;11;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000240-logitech-hd-webcam-c615.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000241-logitech-hd-webcam-c615.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000242-logitech-hd-webcam-c615.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Microsoft Wired LifeCam VX-3000 ";"Microsoft Wired LifeCam VX-3000 ";"
LifeCam VX-3000
 
Die LifeCam VX-3000 begeistert mit leichter Installation und nahtloser Integration in den Windows Live-Messenger. Die kompakte Webcam bietet Top-Bildqualität, kombiniert mit innovativen Features wie der praktischen Windows Live Call-Taste und dem multifunktionalem Standfuß, der sich mit einem Handgriff in eine Halterung für Flachbildschirme verwandeln lässt. Dank integriertem Mikrofon muss kein externes Mikrofon für unterhaltsame Video-Gespräche angeschlossen werden.
 
  Hochauflösende Fotos
Mit hochauflösenden Fotos (1,3 Megapixel interpoliert) zeigen Sie sich von Ihrer besten Seite.
 
Integriertes Mikrofon
Das integrierte Mikrofon erfasst Ihre Stimme automatisch und mit außergewöhnlicher Klarheit.
 
Windows Live Call-Taste
Um einen Videoanruf zu starten, drücken Sie einfach diese Taste, und wählen Sie dann einen Onlinekontakt aus.
 
Software für automatisches Face-Tracking*
Sie können sich bewegen, ohne vom Bildschirm zu verschwinden. Dank modernster Software bleibt Ihr Gesicht stets im Bildmittelpunkt.
 
 
Universalhalterung
Die LifeCam lässt sich problemlos an jedem Monitor befestigen.
 
Kipp-, Dreh- und Zoomfunktion
Die Kamera kann sowohl horizontal als auch vertikal geschwenkt werden und bietet somit ein Höchstmaß an Flexibilität.
 
Flexibles 1,8 m langes Kabel
Das lange, flexible Kabel gibt Ihnen genügend Bewegungsfreiheit.
 
Videoeffekte
Überraschen Sie Ihre Freunde mit coolen Videoeffekten, auf die Sie direkt aus dem Windows Live Messenger-Fenster zugreifen können.
 
Bis zu 30 Bilder pro Sekunde
Die Aufnahmen mit LifeCams erfolgen mit 30 Bildern pro Sekunde, wodurch die Videobilder flüssig und ohne Ruckeln angezeigt werden
 
 
 
 
 
";2;False;0;;;"Microsoft Wired LifeCam VX-3000 ";microsoft-wired-lifecam-vx-3000;True;True;P-2900;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;29.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40889,480775463;27;3;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000237-microsoft-wired-lifecam-vx-3000.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000238-microsoft-wired-lifecam-vx-3000.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000239-microsoft-wired-lifecam-vx-3000.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;SanDisk Secure Dügital Speicherkarte;"SanDisk Secure Digital (SD) Speicherkarte ";"
SanDisk Secure Digital (SD) Speicherkarte 
SecureDigital High Capacity Card (SDHC), entspricht neuem SD-2.0-Standard, Klasse 4
nur geeignet für Endgeräte mit SDHC-Steckplatz (nicht rückwärtskompatibel zu Standard-SD-Cards)
Schutz gegen unbeabsichtigtes Überschreiben der Daten
beliebig oft beschreib- und löschbar
original SanDisk Markenware, Erstausrüsterqualität
";2;False;0;;;SanDisk Secure Digital Speicherkarte;sandisk-secure-duegital-speicherkarte;True;True;P-2890;;;False;0;False;;False;False;0;False;0;1;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;1;9589;False;False;0;1;1;0;False;1;10000;;False;False;False;False;9.8000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40889,4440046296;25;;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000125-sandisk-secure-dugital-speicherkarte.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000126-sandisk-secure-dugital-speicherkarte.jpg;;1;;False;ounce;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Samsung SE-S084D externer DVD Brenner (DVD±RW (±R DL) weiß ";"Samsung SE-S084D externer DVD Brenner (DVD±RW (±R DL) weiß ";"
Samsung SE-S084D – Exklusiver mobiler Brenner mit AV-Funktion.
Der mobile Brenner SE-S084D überzeugt durch Innovation, Funktion und Design. Er setzt neue Maßstäbe und hebt sich in seiner Verarbeitung und den Einsatzmöglichkeiten deutlich von aktuellen Modellen ab.Das hochwertige Finish mit Soft-Touch-Taste und trendiger metallischer Linie machen den schlanken Brenner von Samsung optisch zu einem Highlight. Die Qualität des Produktes gewährt hohe Mobilität und vermittelt allein durch die robuste Haptik Zuverlässigkeit.
 
Angeschlossen wird der Slim-Brenner SE-S084D via HiSpeed-USB. Ein zusätzliches Netzteil ist nicht notwendig, denn der Multiformatbrenner erreicht seine maximale Brenn- und Lesegeschwindigkeit über die Stromversorgung via USB BUS Power. Der 8fach Brenner ist kompatibel sowohl zu Windows als auch zu MAC Betriebssystemen; diese Kompatibilität wurde auch von beiden Partnern offiziell bestätigt. Somit ist seine grundsätzliche Funktion des Brennens und Lesen von Medien aller Art bestens sichergestellt.
 
Durch die leichte und kompakte Bauweise mit nur 270 Gramm ist er die perfekte Begleitung für Netbook, Notebook oder All-In-One PC.
 
Als zusätzliches Feature hat Samsung die AV-Funktion entwickelt. Unterstützt Ihr Fernseher die Wiedergabe via USB-Port. so lässt sich der SE-S084D an diese neue TV-Generation mit PVR Funktion anschließen und zum Abspielen JPEG, MP3 und AVI-Dateien nutzen. Der SE-S084D kann also auch als Player eingesetzt.
 
Dieses neue Produktkonzept wurde auch mit dem IF Design Award 2010 honoriert.
";2;False;0;;;"Samsung SE-S084D externer DVD Brenner (DVD±RW (±R DL) weiß ";samsung-se-s084d-externer-dvd-brenner-dvdrw-r-dl-weiss;True;True;P-2870;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;69.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40889,4407638889;24;19;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000287-samsung-se-s084d-externer-dvd-brenner-dvdrw-r-dl-weis.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000288-samsung-se-s084d-externer-dvd-brenner-dvdrw-r-dl-weis.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000289-samsung-se-s084d-externer-dvd-brenner-dvdrw-r-dl-weis.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Slim USB DVD CD Blu Ray Laufwerk Gehäuse Case extern IDE / PATA Schwarz ";"Slim USB DVD CD Blu Ray Laufwerk Gehäuse Case extern IDE / PATA Schwarz ";"
Externes USB-Gehäuse für optische Slim Blu-Ray, DVD und CD Laufwerke sowie Brenner
 
verwandelt Ihr internes Laufwerk in ein externes
 
- Hochwertiges Firstcom Gehäuse in Matt-Schwarz
- Unterstützt USB 1.1, USB 2.0 sowie USB 3.0
- Easy to Install / Sehr leichter Einbau
- Automatische Erkennung / Plug & Play bei Windows Me / 2000 / XP / Vista / Windows 7
Mac ab OS 8.6 oder höher (keine Treiber Installation notwendig)
- Stromversorgung über USB (Bus-powered / kein extra Netzteil nötig)
- Gummifüße verhindern ein Rutschen auf der Arbeitsfläche
- Abmessungen: 137 x 135 x 18 (L x B x H mm)
- für Slimline Laufwerke mit ca. 12,7 mm Höhe und IDE Anschluss geeignet
 
Lieferumfang:
1 x externes Slim Gehäuse
1 x USB <-> IDE Board (Schnittstelle zum Laufwerk)
1 x USB-Kabel für die Verbindung
1 x USB-Kabel für die Stromzufuhr
1 x Kurzanleitung
und diverses Einbaumaterial
 
Farbe: Schwarz
 
Kann auch am PC, MAC, Notebook, Sub Notebook, Netbook etc. verwendet werden.
Anmerkung: Ein Laufwerk ist nicht eingebaut und gehört nicht zum Lieferumfang.
";2;False;0;;;"Slim USB DVD CD Blu Ray Laufwerk Gehäuse Case extern IDE / PATA Schwarz ";slim-usb-dvd-cd-blu-ray-laufwerk-gehaeuse-case-extern-ide-pata-schwarz;True;True;P-2840;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;24.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40889,4399305556;24;;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000223-slim-usb-dvd-cd-blu-ray-laufwerk-gehause-case-extern-ide-pata-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000224-slim-usb-dvd-cd-blu-ray-laufwerk-gehause-case-extern-ide-pata-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000225-slim-usb-dvd-cd-blu-ray-laufwerk-gehause-case-extern-ide-pata-schwarz.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Samsung SE-406AB/RSBD extern Slim BluRay Combo Laufwerk;"Samsung SE-406AB/RSBD extern Slim BluRay Combo Laufwerk (CyberLink TrueTheater, 3D Support, USB 2.0) ";"
Erleben Sie HD-Kinospaß mit dem externen Slim Blu-ray Combo-Laufwerk SE-406AB für Ihr Notebook oder PC.
Mit dem neuen Samsung Blu-ray Combo-Laufwerk verbinden Sie Arbeit und Vergnügen perfekt miteinander. Klassisch können Sie mit dem portablen Laufwerk, CDs und DVDs in hoher Qualität lesen und beschreiben. Aber ebenso können Sie mit dem SE-406AB HD-Inhalte am eigenen PC abspielen oder selbst erstellte Inhalte auf DVD oder BD auch an einem Fernseher mit Smart-TV-Funktion ansehen. Der Anschluss geschieht komfortabel über USB.
 
Mit dem schlanken Design fällt das Laufwerk kaum ins Gewicht und lässt sich leicht transportieren. Dank Anschluss über USB benötigt es kein zusätzliches Netzteil und verbraucht nur wenig Energie. Das Samsung BD Combo ist extrem leise im Betrieb und zeichnet sich durch eine hohe Kompatibilität und überzeugende Brennergebnisse aus. Die unterstützte Buffer Under Run-Technologie verhindert Pufferunterlauffehler und ermöglicht das Beschreiben von Medien mit hoher Brenngeschwindigkeit.
 
Mit der beiliegenden Software CyberLink BluRay Disc Suite 7 lässt sich das Combo-Laufwerk bequem bedienen. Sie können mit dem Laufwerk und einem 3D-fähigen Display Ihre 2D-DVD-Filmsammlung jetzt auch in 3D erleben. Denn die Software kann 2D-Filme in plastische 3D-Bilder umwandeln. Möglich wird dies mit der CyberLink TrueTheater 3D-Software. Voraussetzung dafür ist natürlich, dass der Nutzer ein 3D-fähiges Anzeigegerät samt 3D-Brille besitzt.
 
Durch das Feature der AV-Konnektivität lässt sich das Gerät an Fernseher mit Smart TV-Funktion anschließen. Smart TV führt Online- und Offline-Inhalte auf dem Fernseher zu einem ganzheitlichen Erlebnis zusammen. So lassen sich gestreamte Medieninhalte in den Formaten JPEG, MP3 und AVI auf dem TV Gerät mit SMART Funktion wiedergeben. Das Laufwerk wird dazu einfach an die USB-Schnittstelle des Fernsehers angeschlossen und fungiert dabei wie ein USB-Stick. Dies ermöglicht das Auslesen der Inhalte auf dem Datenträger. Durch die Verbindung per USB-Anschluss ist der schnelle Zugriff auf Videos, Musik und Fotos gewährleistet.
 
Ein Beispiel für die Multifunktionalität des schicken Laufwerks:
Für Oma schnell eine Foto-DVD brennen, auf dem Notebook eine neue Software aufspielen und selbstgedrehte BD-Filme bearbeiten und anschließend auf dem Fernseher ansehen? Das Samsung Blu-ray Combo-Laufwerk SE-406AB erfüllt Ihnen all diese Wünsche.
";2;False;0;;;LSamsung SE-406AB/RSBD extern Slim BluRay Combo Laufwerk;samsung-se-406abrsbd-extern-slim-bluray-combo-laufwerk;True;True;P-2850;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;79.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40889,4370833333;24;;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000226-samsung-se-406abrsbd-extern-slim-bluray-combo-laufwerk.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000227-samsung-se-406abrsbd-extern-slim-bluray-combo-laufwerk.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000228-samsung-se-406abrsbd-extern-slim-bluray-combo-laufwerk.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Canon Pixma MP 630 Multifunktionsgerät;"Canon Pixma MP 630 Multifunktionsgerät ";"
Canon PIXMA MP620

Hochwertiges Multifunktionssystem mit 9.600-dpi*-Drucksystem und nur 1 Picoliter feinen Tintentröpfchen für Fotos und Dokumente in überragender Druckqualität. Erweiterte Funktionen zum Druckmedien-Handling für die Digitalfotografie, kreative Arbeiten und anspruchsvolle Privatanwender. Features
Drucken, Kopieren und Scannen
Brillante Fotoprints mit 9.600 x 2.400 dpi und 1 Picoliter feinen Tintentröpfchen*
Randlose Fotos im Format 10 x 15 cm in ca. 20 Sekunden*
5-Tintensystem
6,2 cm großes TFT-Farbdisplay mit Easy-Scroll-Bedienrad
Scanner mit 4.800 dpi
Direktscan auf Speicherkarte oder USB-Stick
CD/DVD–Druck
Automatische Duplexfunktion
 
Foto- und Dokumentdruck
Das hochwertige 9.600-dpi*-Drucksystem des PIXMA MP630 mit FINE-Druckkopf für bis zu 1 Picoliter feine Tintentröpfchen liefert beeindruckende Fotoprints. Der Druck eines randlosen Fotos im Format 10 x 15 cm erfolgt in ca. 20 Sekunden*.Die 1 Picoliter feinen Tintentröpfchen der neuen farbstoffbasierten Tinten – inkl. Fotoschwarz – erzeugen kontrastreiche Prints mit sanften Farbabstufungen und brillanten Details.
 
ChromaLife100+** ist ein System aus dem FINE-Druckkopf des PIXMA MP630, Canon Originaltinten und ausgewähltem original Canon Fotopapier. Diese drei einzigartigen Komponenten erzeugen brillante Fotoprints mit hoher Farbstabilität. Textdokumente können in Schwarzweiß oder Farbe gedruckt werden, wobei eine schwarze Pigmenttinte für gestochen scharfen Text sorgt.
 
Single-Ink-Technologie
5 Tintentanks sorgen für Qualität und Effizienz – ist eine Tinte aufgebraucht, muss nur der betreffende Tank ausgetauscht werden.
 
Bedienungsfreundlichkeit
Mit dem hoch auflösenden 6,2 cm großen TFT-Farbdisplay können Sie Ihre Fotos auch ohne Computer bequem ansehen und mit dem Easy-Scroll-Bedienrad durchsuchen, auswählen, bearbeiten und den Druckvorgang starten. Ebenso ist es möglich, Aufnahmen direkt von kompatiblen Speicherkarten, PictBridge-kompatiblen Digitalkameras oder -Camcordern auszudrucken. Mit der Quick-Start-Funktion stehen alle Optionen in wenigen Sekunden zur Verfügung.
 
Fortschrittliches Medien-Handling
Gestalten Sie individuelle bedruckbare CDs und DVDs, indem Sie mit der Software CD-LabelPrint Layouts mit Ihren Texten und Bildern erstellen. Die integrierte Duplexeinheit ermöglicht den automatischen beidseitigen Druck auf Normalpapier, was Papier spart. Zwei Papierzuführungen ermöglichen das gleichzeitige Bestücken des Druckers z. B. mit Normalpapier und Fotopapier.
 
Scannen
Dank der optischen Auflösung von 4.800 dpi sind hervorragende Farbscans möglich, die Sie direkt an den PC oder als E-Mail senden bzw. als PDF erstellen können. Die intuitive Software MP Navigator EX gewährleistet eine einfache Bedienung. Der Auto-Scan-Modus beschleunigt den Scanvorgang, indem der Vorlagentyp erkannt und die entsprechenden Einstellungen automatisch gewählt werden. Mit der praktischen Option zum Direktscan auf Speicherkarte oder USB-Stick können die gescannten Daten einfach und flexibel gespeichert und transportiert werden.
 
Betriebssysteme
Kompatibel mit Windows und Mac OS X
";2;False;0;;;Canon Pixma MP 630 Multifunktionsgerät;canon-pixma-mp-630-multifunktionsgeraet;True;True;P-2180;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;169.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40889,4313888889;"22;2095";25;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000133-canon-pixma-mp-630-multifunktionsgerat.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000134-canon-pixma-mp-630-multifunktionsgerat.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000135-canon-pixma-mp-630-multifunktionsgerat.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Apple iPhone 4S schwarz ";"Apple iPhone 4S schwarz ";"
Das neue iPhone 4S - jetzt mit Dual Core A5 Chip, neuer 8 MegaPixel-Kamera, iOS 5 und iCloud sowie dem neuen Siri.
 
Dual-Core A5 Chip. Der leistungsstärkste iPhone Prozessor aller Zeiten.
Mit zwei Prozessorkernen liefert der A5 Chip bis zu 2x mehr Leistung und bis zu 7x schnellere Grafik. Das wirst du merken. Und zwar schnell. Das iPhone 4S reagiert extrem schnell, was du sofort merkst, wenn du Apps öffnest, im Web surfst, beim Spielen und auch bei allem anderen. Und ganz egal was du machst, du kannst es richtig lange machen. Denn der A5 Chip ist so effizient, dass das iPhone 4S eine enorm lange Batterielaufzeit hat.
 
Die Kaum-zu-glauben-dass-es-ein-Handy-ist Kamera.
Wahrscheinlich die beste Kamera, die es je auf einem Telefon gab. Und dank fortschrittlichster Optik ist sie wahrscheinlich auch die einzige Kamera, die du brauchst. Schließlich hat sie eine Auflösung von 8 Megapixeln und eine spezielle Linse mit einer größeren f/2,4 Blende. Außerdem bietet sie einen optimierten rückwärtig belichteten Sensor, exzellenten Weißabgleich, verbesserte Farbgenauigkeit, Gesichtserkennung und reduzierte Bewegungsunschärfe. Es ist also ganz egal, wie viele Leute, wie viel Licht und wie viel Action du aufnimmst – alles sieht genau so aus, wie es aussehen soll. Und warte erst, bis du die Fotos siehst.
 
Siri. Dein intelligenter, hilfsbereiter Assistent.Du musst ihn nur fragen.
Jetzt kannst du dein iPhone einfach mit deiner Stimme benutzen. Sprich mit Siri so, wie du mit einer Person sprichst und sag ""Erinnere mich daran, Mama anzurufen, wenn ich zu Hause bin"" oder ""Brauche ich einen Schirm?"". Siri spricht Deutsch und versteht nicht nur, was du sagst, sondern auch was du meinst. Es erkennt, welche Apps für die richtige Antwort nötig sind. Und antwortet dir dann – wie dein persönlicher Assistent. Siri telefoniert, sendet Nachrichten, plant Meetings, legt Erinnerungen fest und mehr. Was noch? Frag einfach, und Siri sagt es dir selbst.
 
Videoaufnahmen. In fantastischem 1080p HD.
Nimm fantastische 1080p HD Videos auf, wo immer du bist. Durch die neue fortschrittliche Optik der Kamera ist das Licht immer genau richtig, die Farben immer leuchtend und alles sieht noch besser aus, als du es in Erinnerung hattest. Die Bildstabilisierung gleicht verwackelte Aufnahmen aus. Und du kannst Videos direkt auf dem iPhone bearbeiten und so schnell mit anderen teilen, wie du sie aufnimmst.
 
iOS. Das fortschrittlichste mobile Betriebssystem der Welt. Und auch das einfachste.
Jede neue iOS Version bietet Möglichkeiten, die alles noch einfacher machen. Deshalb ist iOS allen anderen um Jahre voraus. Und iOS 5 geht wieder einen großen Schritt weiter und bringt mehr als 200 neue Features auf das iPhone 4S. Hier sind nur einige unserer Favoriten.
 
iCloud. Deine Inhalte. Auf all deinen Geräten.
Mit iCloud kannst du deine Inhalte ganz einfach verwalten, denn iCloud erledigt alles für dich. iCloud speichert deine Musik, Fotos, Apps, Mails, Kontakte, Kalender, Dokumente und mehr und pusht alles drahtlos an all deine Geräte. Automatisch, nahtlos und einfach so.
 
Retina Display.Das ist ganz klar.
Auf dem iPhone 4S siehst du einfach alles gestochen scharf und lebendig. Das Retina Display ist das höchstauflösende Telefondisplay aller Zeiten. Die Pixeldichte ist so hoch, dass das menschliche Auge keine einzelnen Pixel erkennen kann. Was du aber ganz bestimmt siehst, sind gestochen scharfe Texte, Grafiken und Bilder. Alles sieht sogar noch besser aus als gedruckt.
 
FaceTime. Wink doch mal hallo.
Mit FaceTime hörst du nicht nur eine Stimme, sondern siehst auch das Gesicht dazu – von iPhone zu iPhone, iPad 2, iPod touch oder Mac über Wi-Fi. Es ist also ganz egal, wo die anderen sind und wo du bist – du bist immer da. FaceTime Anrufe sind so einfach wie ganz normale Anrufe. Und mit Siri sind sie sogar noch einfacher. Sag Siri einfach, dass du mit deiner Mutter facetimen willst, und schon seht ihr euch. Einfach so. Du verpasst nie wieder ein wichtiges Ereignis, Meeting oder einen guten Lacher. Und wer würde sich nicht darüber freuen, dich zu sehen?
 
AirPlay. Live vom iPhone auf deinen Fernseher.
Mit AirPlay kannst du Inhalte von deinem iPhone via Apple TV drahtlos an deinen HD Fernseher und Lautsprecher streamen.6 Und mit der AirPlay Synchronisierung erscheint alles, was du auf deinem iPhone siehst oder machst, gleichzeitig auf deinem HD Fernseher.
 
AirPrint.Alles drahtlos drucken.
Drucke deine Mails, Fotos, Webseiten und Dokumente einfach über Wi-Fi von deinem iPhone aus.7 Ganz ohne Software zu laden, Treiber zu installieren oder Kabel anzuschließen. Nur ein paar Fingertipps und schon hast du das, was eben noch auf dem iPhone war, als Ausdruck in der Hand.
 
Besser. Schneller. Weltweiter.
Das iPhone 4S ist das erste Telefon, das zum Übertragen und Empfangen intelligent zwischen zwei Antennen wechselt. So ist die Anrufqualität deutlich besser. Außerdem verdoppeln die Antennen die maximale HSDPA Datengeschwindigkeit auf 14,4 Mbit/s.8 Und das bedeutet schnellere Verbindungen, schnelleres Laden und Neuladen und schnellere Downloads. Das iPhone 4S ist ein Telefon für die ganze Welt. Du kannst es also fast überall verwenden. Ob GSM- oder CDMA-Standard spielt keine Rolle. Nutze es via Roaming in GSM-Netzen in 200 Ländern weltweit.
 
Integrierte Apps. Machen alles, damit du alles machen kannst.
Ganz Alltägliches erledigst du mit dem iPhone 4S auf ganz außergewöhnliche Weise. Mach fantastische Fotos und nimm HD Videos auf. Sieh Freunde und Familie mit FaceTime. Tauche auf dem Retina Display richtig ins Web ein. Check deine Mails. Sende Nachrichten. Lege Erinnerungen fest. Schau in deinen Kalender. Oder sag Siri einfach, wie es dir helfen soll. Siri findet dann selbst heraus, welche Apps es verwenden muss.
Aufgrund der sehr umfangreichen Leistungsmerkmale können wir Ihnen hier nur einen Auszug präsentieren. Die vollständigen Funktionsbeschreibungen inkl. einer Vielzahl von Videos entnehmen Sie bitte der Herstellerwebseite.
•Apple iPhone 4S
•115,2 x 58,6 x 9,3 mm klein und 140 g leicht
•Kapazität: 16 GB Flash-Laufwerk
•Kamera, Fotos und Video:
• 8.0 Megapixel Kamera
• Videoaufnahme, HD (1080p) bis zu 30 fps mit Audio
• Fotos und Videos in VGA-Qualität mit bis zu 30 fps mit der Kamera an der Vorderseite
• Fokussieren per Fingertipp für Videos und Fotos LED-Blitz
• Geotagging für Fotos und Videos
•Display:
• Retina Display
• 3,5""-Multitouch-Display (8,89 cm Diagonale)
• Auflösung von 960 x 640 Pixeln mit 326ppi
• Typisches Kontrastverhältnis: 800:1
• Fettabweisende Beschichtung an der Vorder- und Rückseite
• Unterstützung für die Anzeige mehrerer Sprachen und Zeichen gleichzeitig
•Stromversorgung und Batterie:
• Sprechdauer: bis zu 8 Std. mit 3G, bis zu 14 Std. mit 2G
• Standbydauer: bis zu 200 Std.
• Internetnutzung: bis zu 6 Std. mit 3G, bis zu 9 Std. mit Wi-Fi
• Videowiedergabe: bis zu 10 Std., Audiowiedergabe: bis zu 40 Std.
•Betriebssystem: iOS 5
•Mobilfunknetz und Wi-Fi:
• UMTS/HSDPA/HSUPA (850, 900, 1900, 2100 MHz)
• GSM/Edge (850, 900, 1800, 1900 MHz)
• Funktechnologie: 802,11b/g/n Wi-Fi (802.11 nur mit 2,4 GHz), Bluetooth 4.0
•GPS: Assisted GPS
•Digitaler Kompass
•Unterstützte Audioformate: AAC (8 bis 320 KBit/Sek.), Protected AAC (aus dem iTunes Store), HE-AAC, MP3 (8 bis 320 KBit/Sek.), MP3 VBR, Audible (Formate 2, 3, 4, Audible Enhanced Audio, AAX und AAX+), Apple Lossless, AIFF und WAV
•TV und Video: AirPlay Mirroring to Apple TV support at 720p, Video mirroring and video out support: Up to 1080p with Apple Digital AV Adapter or Apple VGA Adapter (adapters sold separately), Video out support at 576p and 480p with Apple Component AV Cable; 576i and 480i with Apple Composite AV Cable (cables sold separately)
•Unterstützte Videoformate: H.264 Video: bis zu 720p, 30 Bilder pro Sekunde, Main Level Profile Level 3.1 mit AAC-LC Audio bis zu 160 KBit/Sek., 48 kHz, Stereo-Audio in den Formaten .m4v, .mp4 und .mov; MPEG.4 Video: bis zu 2,5 MBit/Sek., 640 x 480 Pixel, 30 Bilder pro Sekunde, Simple Profile mit AAC-LC Audio bis zu 160 KBit/Sek., 48 kHz, Stereo-Audio in den Formaten .m4v, .mp4 und .mov; Motion JPEG (M-JPEG): bis zu 35 MBit/Sek., 1280 x 720 Pixel, 30 Bilder pro Sekunde, Audio im Format ulaw, PCM Stereo-Audio im Format .avi
•Sensoren:
• 3-Achsen-Gyrosensor
• Beschleunigungssensor
• Annäherungssensor
• Umgebungslichtsensor
 
Lieferumfang:
iPhone 4S, Apple Earphones mit Fernbedienung und Mikrofon, Dock Connector-auf-USB-Kabel, Dokumentation
";2;False;0;;;"Apple iPhone 4S schwarz ";apple-iphone-4s-schwarz;True;True;PD-01081;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;639.0000;639.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40885,5442708333;71;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000651-apple-iphone-4s-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000652-apple-iphone-4s-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000653-apple-iphone-4s-schwarz.jpg;1;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;AVM FRITZ! Box WLAN 3270;AVM FRITZ! Box WLAN 3270 mit 300 Mbit/s und WLAN Eco-Mode;"
FRITZ!Box WLAN 3270
Einfach, sicher, kabellos surfen und vernetzen!
 
FRITZ!Box WLAN 3270 verbindet alle Ihre Computer mit dem Internet - rasend schnell über ADSL oder ADSL2+ und kabellos mit dem neuen WLAN 802.11n.
 
FRITZ!Box WLAN 3270 vereint ein DSL-Modem mit einem WLAN N-Router in einem Gerät. Mit modernem WLAN N bietet die FRITZ!Box übertragungsgeschwindigkeiten von bis zu 300 MBit/s beim kabellosen Surfen. Computer und netzwerkfähige Geräte lassen sich zudem über die vier Ethernet-Schnittstellen anschließen. Dank des USB-Anschlusses (USB 2.0) stehen Drucker und Speicher im ganzen Netzwerk zur Verfügung.
 
Ein Hi-Speed-USB 2.0-Anschluss und die erweiterte NAS-Funktionalität mit Mediaserver und Onlinespeicher-Integration erschließen neue Anwendungsmöglichkeiten im Netzwerk.
 
Damit sind Inhalte wie Filme, Musik und Bilder auch bei ausgeschaltetem Computer im gesamten Netzwerk verfügbar und können auf UPnP-AV-fähigen Geräten (z. B. HD-Fernseher oder Stereoanlage) wiedergegeben werden.
 
 FRITZ!Box WLAN 3270 verfügt über eine umfangreiche Softwareausstattung. Dazu gehören beispielsweise Firewall, Kindersicherung, VPN, WLAN-Nachtschaltung und WLAN-Autokanal.
 
WLAN N
FRITZ!Box WLAN 3270 ermöglicht WLAN-Verbindungen mit dem Funkstandard 802.11n im 2,4-GHz- oder im besonders störungsarmen 5-GHz-Band. Durch das Mehrantennenverfahren MIMO (Multiple Input Multiple Output) erhöhen sich Reichweite, Qualität und Datenrate der WLAN-Verbindung. FRITZ!Box WLAN 3270 ist bereits ab Werk sicher dank der voreingestellten, individuellen WPA-/WPA2-Verschlüsselung.
 
Energie sparen mit FRITZ!
Mit dem Eco-Mode passt FRITZ!Box WLAN 3270 die Funkleistung automatisch an den Datenverkehr an und sorgt für optimalen Stromverbrauch. Im Ruhezustand wird die Prozessorleistung minimiert und ungenutzte Schnittstellen werden abgeschaltet. Die Funkdauer kann dank der WLAN-Nachtschaltung beliebig eingestellt oder mit einem Schalter verändert werden.
 
Mehr Möglichkeiten mit USB 2.0
Ein Hi-Speed-USB 2.0-Anschluss ermöglicht neue Anwendungen im Netzwerk. Bilder, Musik und Videos von an der FRITZ!Box angeschlossenen Speichermedien können an UPnP-AV-kompatiblen Empfängern (HD-Fernseher, Stereoanlage) wiedergegeben werden. Zusätzlich kann ein USB-Drucker dem gesamten Netzwerk zur Verfügung gestellt werden.
 
Egal ob Online- oder USB-Speicher - die integrierte FRITZ!NAS-Webseite (http://fritz.nas) bietet eine einfache und komfortable Möglichkeit, zentral auf alle Datenbestände an der FRITZ!Box zuzugreifen. Auf Wunsch auch über das Internet.
 
Anschlüsse
- DSL-Anschluss an ADSL2+ und ADSL.
 
- Routerbetrieb auch mit Kabelmodem oder UMTS-Stick (UMTS/HSPA).
 
- WLAN-Funknetze nach gängigen Standards (802.11n/g/b/a).
 
- 4 x Ethernet (10/100 Base-T) für Anschluss und Vernetzung von Computern und Spielekonsolen.
 
- USB 2.0-Anschluss für USB-Geräte wie Drucker und Speichermedien oder UMTS-Stick.
";2;False;0;;;AVM FRITZ! Box WLAN 3270 mit 300 Mbit/s und WLAN Eco-Mode;avm-fritz-box-wlan-3270;True;True;P-2690;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;169.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40871,807349537;18;34;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000206-avm-fritz-box-wlan-3270.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000207-avm-fritz-box-wlan-3270.jpg;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;AVM FRITZ!Box Fon WLAN 7390;AVM FRITZ!Box Fon WLAN 7390;"
FRITZ!Box Fon WLAN 7390
Mehr Leistung für Internet, Telefon und digitale Medien.
 
FRITZ!Box Fon WLAN 7390 verbindet alle Ihre Computer mit dem Internet - rasend schnell über VDSL (bis 100 MBit/s) oder ADSL2+/ADSL (bis 16 MBit/s). Der neue WLAN-Standard 802.11n (WLAN N) sorgt für ein Maximum an Geschwindigkeit und Reichweite beim kabellosen Surfen. Und dank integrierter DECT-Basisstation und HD-Telefonie wird das Telefonieren über das Internet zu einem komfortablen Erlebnis.
 
FRITZ!Box Fon WLAN 7390 bietet eine bisher nicht erreichte Vielfalt an Anwendungen für den DSL-Anschluss. Der neue WLAN N-Funkstandard sorgt in Verbindung mit der MIMO- Mehrantennentechnik für eine optimale übertragung mit 2,4 und 5 GHz gleichzeitig (Dualband).
 
Für die Internet- und Festnetztelefonie steht neben Anschlüssen für analoge und ISDN- Telefone auch eine integrierte DECT-Basis- station für bis zu 6 Schnurlostelefone zur Verfügung.
 
FRITZ!Box Fon WLAN 7390 bietet dank leistungsstarkem Prozessor die Plattform für vernetzte Anwendungen wie IPTV, Video on Demand oder Mediastreaming.
 
 Zwei Hi-Speed-USB 2.0-Anschlüsse der FRITZ!Box Fon WLAN 7390 und die erweiterte NAS-Funktionalität mit Mediaserver und Onlinespeicher-Integration erschließen neue Anwendungsmöglichkeiten im Netzwerk. Damit sind Inhalte wie Filme, Musik und Bilder auch bei ausgeschaltetem Computer im gesamten Netzwerk verfügbar und können auf UPnP-AV-fähigen Geräten (z. B. HD-Fernseher oder Stereoanlage) wiedergegeben werden.
 
FRITZ!Box Fon WLAN 7390 verfügt über eine umfangreiche Softwareausstattung. Dazu gehören beispielsweise Telefonbuch, Firewall, Kindersicherung, Faxempfang, VPN, WLAN-Nachtschaltung, WLAN-Autokanal oder ein integrierter Anrufbeantworter.
 
Dual-WLAN N
FRITZ!Box Fon WLAN 7390 ermöglicht WLAN-Verbindungen mit dem Funkstandard 802.11n im 2,4-GHz- und im besonders störungsarmen 5-GHz-Band gleichzeitig. Durch das Mehrantennenverfahren MIMO (Multiple Input Multiple Output) erhöhen sich Reichweite, Qualität und Datenrate der WLAN-Verbindung. FRITZ!Box Fon WLAN 7390 ist bereits ab Werk sicher dank der voreingestellten, individuellen WPA-/WPA2-Verschlüsselung.
 
DECT-Basisstation
Durch die integrierte DECT-Basisstation können Sie mit bis zu sechs Mobilteilen schnurlos telefonieren. Als ideale Ergänzung zur FRITZ!Box Fon WLAN 7390 bietet AVM die schnurlosen Telefone FRITZ!Fon MT-D und MT-F an, mit denen zahlreiche Komfortfunktionen sowie brillante HD-Telefonie genutzt werden können.
 
Energie sparen mit FRITZ!
Mit dem Eco-Mode passt FRITZ!Box Fon WLAN 7390 die Funkleistung automatisch an den Datenverkehr an und sorgt für optimalen Stromverbrauch. Im Ruhezustand wird die Prozessorleistung minimiert und ungenutzte Schnittstellen werden abgeschaltet. Die Funkdauer kann dank der WLAN-Nachtschaltung beliebig eingestellt oder mit einem Schalter verändert werden.
 
Mehr Möglichkeiten mit USB 2.0
Zwei Hi-Speed-USB 2.0-Anschlüsse ermöglichen neue Anwendungen im Netzwerk. Bilder, Musik und Videos von an der FRITZ!Box angeschlossenen Speichermedien können an UPnP-AV-kompatiblen Empfängern (HD-Fernseher, Stereoanlage) wiedergegeben werden. Zusätzlich kann ein USB-Drucker dem gesamten Netzwerk zur Verfügung gestellt werden.
 
Egal ob interner, Online- oder USB-Speicher - die integrierte FRITZ!NAS-Webseite (http://fritz.nas) bietet eine einfache und komfortable Möglichkeit, zentral auf alle Datenbestände an der FRITZ!Box zuzugreifen. Auf Wunsch auch über das Internet.
 
7390-3.jpg
";2;False;0;;;AVM FRITZ!Box Fon WLAN 7390;avm-fritzbox-fon-wlan-7390;True;True;P-2700;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;289.0000;289.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40871,8066898148;18;34;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000103-avm-fritzbox-fon-wlan-7390.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000104-avm-fritzbox-fon-wlan-7390.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000105-avm-fritzbox-fon-wlan-7390.jpg;1;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"AVM FRITZ!Box Fon WLAN 7270 ";"AVM FRITZ!Box Fon WLAN 7270 ";"
FRITZ!Box Fon WLAN 7270
Kabellos mit DSL surfen und über das Internet telefonieren.
 
FRITZ!Box Fon WLAN 7270 verbindet alle Ihre Computer mit dem Internet - rasend schnell über ADSL oder ADSL2+ und kabellos mit dem neuen WLAN 802.11n.
 
FRITZ!Box Fon WLAN 7270 vereint DSL-Modem und WLAN-Router mit einer Telefonanlage für Internet- (VoIP-) und Festnetztelefonie und kann wahlweise an analogen oder ISDN-Anschlüssen eingesetzt werden. Sowohl analoge als auch ISDN- und DECT-Telefone werden durch FRITZ!Box Fon WLAN 7270 mit dem Internet und Festnetz verbunden. Das können bis zu zwei analoge Endgeräte wie Telefon und Fax sein, eine ISDN-TK-Anlage, aber auch bis zu sechs Schnurlostelefone, die sich einfach mit der in der FRITZ!Box Fon WLAN 7270 integrierten DECT-Basisstation verbinden lassen.
 
Unabhängig von der Art des Anschlusses stehen alle wesentlichen Leistungsmerkmale wie Rufnummernanzeige, Dreierkonferenz, Rufumleitung und Makeln an den Telefonen zur Verfügung. Internettelefonie in HD-Qualität (High Definition) wird durch den Einsatz von Breitband-Sprachcodecs unterstützt.
 
 FRITZ!Box Fon WLAN 7270 bietet mit modernem WLAN N übertragungsgeschwindigkeiten von bis zu 300 MBit/s. Computer und netzwerkfähige Geräte lassen sich zudem über die vier LAN-Schnittstellen anschließen. Dank des USB-Anschlusses (USB 2.0) stehen Drucker und Speicher im ganzen Netzwerk zur Verfügung.
 
FRITZ!Box Fon WLAN 7270 verfügt über eine umfangreiche Softwareausstattung. Dazu gehören beispielsweise Telefonbuch, integrierter Anrufbeantworter, Faxempfang, WLAN-Nachtschaltung, Kindersicherung und VPN.
 
WLAN N
FRITZ!Box Fon WLAN 7270 ermöglicht WLAN-Verbindungen mit dem Funkstandard 802.11n im 2,4-GHz- oder im besonders störungsarmen 5-GHz-Band. Durch das Mehrantennenverfahren MIMO (Multiple Input Multiple Output) erhöhen sich Reichweite, Qualität und Datenrate der WLAN-Verbindung. FRITZ!Box Fon WLAN 7270 ist bereits ab Werk sicher dank der voreingestellten, individuellen WPA-/WPA2-Verschlüsselung.
 
DECT-Basisstation
Durch die integrierte DECT-Basisstation können Sie mit bis zu sechs Mobilteilen schnurlos telefonieren, wenn diese den Standard CAT-iq oder GAP unterstützen. Als ideale Ergänzungen zur FRITZ!Box bietet AVM die schnurlosen Telefone FRITZ!Fon MT-F und FRITZ!Fon MT-D an, mit denen Sie zahlreiche Komfortfunktionen sowie Internettelefonie in HD-Qualität nutzen können.
 
Energie sparen mit FRITZ!
Mit dem Eco-Mode passt FRITZ!Box Fon WLAN 7270 die Funkleistung automatisch an den Datenverkehr an und sorgt für optimalen Stromverbrauch. Im Ruhezustand wird die Prozessorleistung minimiert und ungenutzte Schnittstellen werden abgeschaltet. Die Funkdauer kann dank der WLAN-Nachtschaltung beliebig eingestellt oder mit einem Schalter verändert werden.
 
Mehr Möglichkeiten mit USB 2.0
Ein Hi-Speed-USB 2.0-Anschluss ermöglicht neue Anwendungen im Netzwerk. Bilder, Musik und Videos von an der FRITZ!Box angeschlossenen Speichermedien können an UPnP-AV-kompatiblen Empfängern (HD-Fernseher, Stereoanlage) wiedergegeben werden. Zusätzlich kann ein USB-Drucker dem gesamten Netzwerk zur Verfügung gestellt werden.
 
Egal ob Online- oder USB-Speicher - die integrierte FRITZ!NAS-Webseite (http://fritz.nas) bietet eine einfache und komfortable Möglichkeit, zentral auf alle Datenbestände an der FRITZ!Box zuzugreifen. Auf Wunsch auch über das Internet.
";2;False;0;;;AVM FRITZ!Box Fon WLAN 7270 N-Standard mit bis zu 300 MBit/Sek;avm-fritzbox-fon-wlan-7270;True;True;;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;249.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40871,8016898148;18;34;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000200-avm-fritzbox-fon-wlan-7270.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000201-avm-fritzbox-fon-wlan-7270.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000202-avm-fritzbox-fon-wlan-7270.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Samsung SyncMaster P2270 HD 22 Zoll TFT Monitor ";Samsung SyncMaster P2270 HD 22 Zoll TFT Monitor schwarz;"
Samsung P2270HD
Die SyncMaster 70er HD-Serie besticht mit edlem Design und technischen Raffinessen: So können die Modelle dieser Serie als LCD-Monitor, aber auch als vollwertiges LCD-TV-Gerät eingesetzt werden. Der integrierte TV Tuner macht es möglich. Vielseitige AV-Anschlussmöglichkeiten bieten zudem die Möglichkeit, weitere Peripheriegeräte anzuschließen. Das praktische 16:9-Format mit Full HD Auflösung und die Unterstützung von Dolby Digital Plus und SRS TruSurround HD runden die multimedialen Eigenschaften dieser Serie ab.
 
TV Tuner
Dieses SyncMaster-Modell ist mit einem TV Tuner ausgestattet und kann somit auch als vollwertiges LCD-TV-Gerät verwendet werden.
 
16:9-Widescreen-Format
Das praktische 16:9-Widescreen-Format ermöglicht ein noch angenehmeres Arbeiten bei gleichzeitiger Steigerung Ihrer Produktivität. Das Breitbildformat entspricht dem natürlichen Sichtfeld des Betrachters. Somit haben Sie immer alles im Blick, ohne auf wichtige Informationen verzichten zu müssen.
 
Full HD
Dieses SyncMaster Large Format Display verfügt über ein Full HD Panel mit einer nativen Auflösung von 1.920 x 1.080 Pixel. Somit können Bildinhalte im 1.080p-Format, der derzeit besten HD-Auflösung, wiedergegeben werden. 
 
Dynamischer Kontrast
Genießen Sie beste Bildqualität mit hoher Bildschärfe und Detailreichtum selbst in dunklen Szenen. Mit einem dynamischen Kontrast von bis zu 50.000:1 werden Sie jedes Detail auf dem Bildschirm erkennen können.
 
HDMI
HDMI steht für High Definition Multimedia Interface. Mit dieser Schnittstelle ist es möglich, HD Bild- und Tonmaterial in 100% verlustfreier, digitaler Qualität zu übertragen.
 
MagicSpeed
MagicSpeed garantiert Ihnen selbst bei schnell bewegten Bildschirminhalten, wie z. B. Filmen oder Computerspielen, eine schlierenfreie Darstellung für beste Bildqualität. 
  
HDCP
HDCP oder auch High Bandwidth Digital Content Protection schützt urheberrechtlich geschützte Formate (z. B. Videodaten) vor illegalen Kopien. HDCP muss dabei sowohl vom Quellgerät (z. B. DVD-Player) als auch vom Ausgabegerät (Monitor) unterstützt werden. Dieses SyncMaster-Modell ist HDCP-kompatibel.
 
Energiesparfunktion
Samsung Displays, die dieses Logo tragen, sind besonders energieeffizient und schonen somit die Umwelt.
 
RoHS-Zertifikat
Die Displays von Samsung wurden von Nemko mit dem RoHS-Logo zertifiziert, d. h. sie enthalten keine gefährlichen Substanzen gemäß den Richtlinien der Europäischen Union. Damit ist Samsung der erste Hersteller am Markt, der offiziell diese Zertifizierung erhalten hat. 
 
";2;False;0;;;Samsung SyncMaster P2270 HD 22 Zoll;samsung-syncmaster-p2270-hd-22-zoll-tft-monitor;True;True;P-2480;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;199.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40871,5791087963;9;5;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000462-samsung-syncmaster-p2270-hd-22-zoll-tft-monitor.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000463-samsung-syncmaster-p2270-hd-22-zoll-tft-monitor.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000464-samsung-syncmaster-p2270-hd-22-zoll-tft-monitor.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Apple iPod Touch 8 GB schwarz;Apple iPod Touch 8 GB schwarz;"
Apple iPod Touch 8 GB schwarz
 
mit integrierter WiFi Funktion

 
Ein großartiger iPod. Ein großartiger Taschencomputer. Großartiger mobiler Spielspaß. Und das Ganze in einem unglaublich schlanken, eleganten neuen Design aus Edelstahl. Filme, Videos und Fernsehsendungen auf einem 3,5"" Display ansehen!Im Web surfen, mailen! Multitouch-Oberfläche: Die revolutionäre Technologie des iPhone und die Software Version 3.1 stecken in diesem genialen iPod. Das brillante Breitformat-Display rückt Ihre Videos und Spiele ins beste Licht Surfen Sie mit Safari im Web und sehen Sie YouTube Videos auf dem iPod mit integrierter Wi-Fi Funktionalität an.
 
Mit Ihrem iPod touch können Sie im iTunes Wi-Fi Music Store nach Songs suchen, Hörproben abspielen und Titel kaufen.  Lieferumfang: iPod touch, Ohrhörer, USB 2.0 Kabel, Dock-Adapter, Kurzanleitung
 
Der iPod touch kann alles, was du am iPod toll findest. Und noch vielmehr.
Du kannst Filme, Videos und Fernsehsendungen auf einem 3,5"" Display ansehen. Mit der revolutionären Multi-Touch-Technologie kannst du dein Musikarchiv mit Cover Flow durchblättern. Und wenn dir nach mehr ist, tipp einfach auf iTunes, um durch das Angebot zu stöbern und sofort einzukaufen. Hör dir Wiedergabelisten an, die automatisch für dich erstellt werden. Schau Filme auf dem brillanten 3,5"" Display. Und kauf mit einem Fingertipp bei iTunes ein - wann immer du willst. All das und noch viel mehr mit dem iPod touch, den es schon ab 189 € gibt. Wi-Fi ist schon integriert. So kannst du im Web surfen, mailen, deinen Facebook Status aktualisieren, mit AIM chatten und noch viel mehr - und das alles auf einem Gerät, das locker in jede Tasche passt. Hier hast du die Finger im Spiel. Und nicht nur die. Denn mit den Spielen auf dem iPod touch tauchst du richtig in die Action ein - einfach neigen, tippen, drehen. Und via Wi-Fi kannst du jederzeit im App Store neue Spiele kaufen. Die iPhone 3.1 Software ist auf dem iPod touch bereits installiert, sodass der Spaß gleich beginnen kann. Damit kannst du nützliche Funktionen wie Peer-to-Peer-Spiele und Cut, Copy & Paste direkt nach dem Auspacken nutzen.
Next Level Fun: Der neue iPod touch
 
Musik
Stöber durch deine Alben. Hör dir einen einzigartigen Mix an, der nur für dich erstellt wurde. Oder schau das Video deines Lieblingssongs an. Mit dem iPod touch kannst du mehr als nur Musik hören.
 
Cover Flow
Auf dem iPod touch gibt's Musik nicht nur auf die Ohren. Mit Cover Flow ist Musik auch etwas für Augen und Finger. Dreh den iPod touch einfach auf die Seite und blätter durch deine Albumcover. Tipp auf ein Albumcover, um es umzudrehen und die Songliste zu sehen. Tipp noch einmal und Musik ab.
 
Genius Mixe
Die Genius Funktion wurde weiter verbessert. Jetzt gibt es Genius Mixe. Du brauchst den iPod touch nur mit iTunes zu synchronisieren. Genius durchsucht dann automatisch deine Mediathek nach Songs, die gut zusammenpassen und erstellt bis zu zwölf Mixe.
Diese Mixe sind wie Radiosender, auf denen nur deine Musik läuft.
 
Genius Wiedergabelisten
Angenommen du hörst einen Song auf deinem iPod touch, der dir gut gefällt, und du möchtest weitere Titel hören, die dazu passen. Genius findet weitere Songs auf deinem iPod touch und erstellt eine Genius Wiedergabeliste für dich. Hör dir die Wiedergabeliste sofort an, speichere sie für später oder versuch's noch einmal und sieh, was dabei herauskommt. Verlass dich auf Genius, wenn du einen Mix willst, auf den du selbst nie gekommen wärst.
 
Shake to Shuffle
Die Dinge mal aufrütteln. Musikalisch natürlich. Wenn du das nächste Mal Musik hörst, aktiviere die Schüttelfunktion und wenn du den iPod touch dann kurz schüttelst, springt er nach dem Zufallsprinzip zu einem anderen Song aus deiner Sammlung.
 
iTunes
Pack Musik und Videos aus der iTunes Mediathek deines Computers auf den iPod touch. Oder kauf und lade neue Songs auf den iPod touch, wenn du über Wi-Fi auf iTunes zugreifst. Wenn du den iPod touch das nächste Mal mit dem Computer verbindest, werden alle Songs, die du auf dem iPod touch gekauft hast, auf den Mac oder PC übertragen.
 
Bluetooth
Schau mal, keine Kabel. Der iPod touch enthält die iPhone 3.1 Software, sodass du Bluetooth Stereokopfhörer anschließen kannst. Lass den iPod in deiner Tasche stecken oder auf dem Schreibtisch aufladen, während du weiter Musik hörst.
 
Filme und Fernsehsendungen
Ein Kinohit. Ein Video-Podcast. Deine Lieblingsserie. Jetzt laufen sie auch in einer U-Bahn oder einem Flugzeug in deiner Nähe.
Widescreen-Display
Du kannst Videos für viele Stunden überallhin mitnehmen und auf dem gestochen scharfen 3,5"" Widescreen-Farbdisplay ansehen. Kauf im iTunes Store und wähle unter tausenden vonFilmen, Fernsehsendungen und Video-Podcasts, die du auf den iPod touch laden kannst. Von Hollywood-Hits bis zu Indie-Streifen - es gibt etwas für jeden Geschmack. Mit wenigen Fingertipps kannst du Filme kaufen und laden. Du magst lieber Fernsehsendungen? Lade eine einzelne Folge oder die gesamte Staffel.
 
On-Screen Steuerung
Auch während du Video guckst, kannst du die Steuerung einblenden - ein Fingertipp auf das Display genügt. Du kannst die Wiedergabe starten oder unterbrechen, einzelne Kapitel anzeigen und die Lautstärke anpassen. Natürlich kannst du auch die Lautstärkeregler links am iPod touch verwenden. Du willst zwischen Widescreen und bildschirmfüllender Anzeige wechseln? Einfach aufs Display doppeltippen.
 
iTunes
Du brauchst Unterhaltung für deinen nächsten Flug oder die Autofahrt? Mit iTunes auf dem iPod touch und einer Wi-Fi-Verbindung kannst du auch unterwegsFilme und Fernsehsendungen kaufen. Du kannst Filme auch leihen, wenn du dir nicht sicher bist, ob du den Film behalten willst. Und natürlich kannst du Filme und Fernsehsendungen auf dem Mac oder PC kaufen und dann mit dem iPod touch synchronisieren.
 
App Store
Kaufe im App Store und entdecke über 65.000 Apps, mit denen du noch mehr auf dem iPod touch machen kannst. Stöbere in tausenden von Apps in verschiedenen Kategorien. Von Spielen über Lifestyle und Soziale Netzwerke bis zu Unterhaltung und mehr.
 
Apps durchstöbern
Du kannst auf verschiedene Arten im App Store shoppen. Tipp auf ""Neu"" und ""Topaktuell"", um eine Liste der aktuellen und angesagten Apps zu erhalten. Stöbere nach Kategorien. Schau dir die topaktuellen Apps an. Wenn du genau weißt, wonach du suchst, kannst du auch eine Schnellsuche durchführen.
 
Genius Empfehlungen für Apps
Es gibt tausende von Apps im App Store, und jeden Tag kommen mehr dazu. Mit dieser neuen Funktion des iPod touch findest du coole neue Apps noch einfacher. Genius für Apps. Funktioniert genau wie Genius für deine Musik. Tipp auf das Genius Symbol und du bekommst Empfehlungen für Apps anhand der Apps, die du und andere schon geladen haben.
 
Apps laden
Wenn du eine App findest, die dich interessiert, kannst du sie überall, wo eine Wi-Fi-Verbindung besteht, drahtlos kaufen, auf den iPod laden und dann sofort loslegen.
 
Updates für Apps
iPod touch sagt dir, wenn ein App Update verfügbar ist, damit du immer die neuesten Versionen deiner Lieblings-Apps hast.
 
iTunes
Entdecke und lade neue Musik, Filme, Fernsehsendungen, Podcasts und Hörbücher in iTunes auf dem iPod touch.
 
Einkaufen, immer und überall
Greif über die im iPod touch integrierte Wi-Fi-Funktion auf den iTunes Store zu. Durchsuche Millionen von iTunes Plus Songs in brillanter Audioqualitätund tausende von Filmen, Fernsehsendungen, Hörbüchern und kostenlosen Podcasts und Vorlesungen von iTunes U. Stöbere nach Neuerscheinungen, Top-Titeln und Genres. Oder finde mit der Schnellsuche genau das, wonach du suchst. Hör in einen Song oder sieh dir eine Videovorschau an. Wenn du dann etwas kaufen möchtest, brauchst du nur darauf zu tippen. Nicht sicher, ob es sich lohnt, den Film zu kaufen? Dann leih ihn einfach. Alles was du auf dem iPod touch kaufst, hat denselben Preis wie im iTunes Store auf deinem Computer.
 
Synchronisieren mit iTunes
Sobald du den iPod touch mit dem Computer verbindest, werden die Songs, Filme, Fernsehsendungen, Hörbücher und Podcasts, die du unterwegs geladen hast, mit deiner iTunes Mediathek auf deinem Mac oder PC synchronisiert. Wenn du etwas nur teilweise auf den iPod touch geladen hast, beendet der Computer den Download automatisch für dich.
 
Sprachsteuerung
Mit der Sprachsteuerung beim neuen 32 GB und 64 GB iPod touch kannst du deine Musik mit Sprachbefehlen steuern. Und der iPod hört aufs Wort. Auf ""Spiel"", ""Shuffle"" oder ""Wie heißt das Lied?"".
 
Sagen und abspielen.
Die Sprachsteuerung kennt die Musik auf deinem iPod touch. Wenn du etwas Bestimmtes hören willst, sag es einfach. Zum Beispiel ""Spiel Bob Dylan"" und der iPod touch hört aufs Wort. Frag ihn, welcher Song grad läuft, und der iPod touch sagt es dir. Sag ihm, dass er dein Lieblingsalbum, deinen Lieblingssänger oder deine Lieblingswiedergabeliste spielen soll. Verwende einfache Befehle wie ""shuffle"", ""nächster Song"" und ""anhalten"". Du kannst dem iPod touch sogar sagen, dass er mehr Songs wie den, der gerade läuft, abspielen soll.
 
Sprich ins Mikro
Der neue 32 GB und 64 GB iPod touch wird mit den Apple Earphones mit Fernbedienung und Mikro geliefert. So kannst du die Sprachsteuerung auch dann nutzen, wenn der iPod touch in der Tasche steckt. Zum Aktivieren der Sprachsteuerung über die Kopfhörer hältst du einfach die Mitteltaste der Fernbedienung gedrückt.
 
Die Sprachsteuerung unterstützt die folgenden Sprachen:
Chinesisch (China), Chinesisch (Kantonesisch), Chinesisch (Taiwan), Deutsch, Englisch (Großbritannien), Englisch (USA), Finnisch, Französisch (Frankreich), Französisch (Kanada), Italienisch, Japanisch, Koreanisch, Niederländisch, Norwegisch, Polnisch, Portugiesisch (Brasilien), Portugiesisch (Portugal), Russisch, Schwedisch, Spanisch (Mexiko), Spanisch (Spanien)
 
Fotos
Der iPod touch hat für bis zu 90.000 deiner Lieblingsfotos Platz. Durch Streichen kannst du sie durchschauen und all die Erinnerst-du-dich-noch-Momente mit anderen teilen.
 
Fotos sichern
Wenn dir tolle Bilder gemailt werden, kannst du sie einfach im Fotoarchiv auf dem iPod touch sichern und dann wie jedes andere Foto nutzen. Du kannst sie zum Beispiel als Hintergrundbilder verwenden, im Internet teilen oder weitergeben.
 
Fotos teilen
Du hast tausende Fotos immer zur Hand. Blätter durch Streichen auf dem Display durch Miniaturen. Mit einem Fingertipp siehst du Fotos bildschirmfüllend. Spiel Diashows mit Musik und Übergängen ab. Maile Fotos an Freunde oder teile sie in einer MobileMe Galerie.
 
Fotos synchronisieren
Fotos aus iPhoto auf einem Mac oder Adobe Photoshop Elements und Adobe Photoshop Album auf einem PC werden via iTunes mit dem iPod touch synchronisiert. Einfach nur die Fotos und Alben aussuchen, die mit dem iPod touch synchronisiert werden sollen. Dann kannst du sie überall ansehen und mit anderen teilen.
 
Homescreen
Angenommen du möchtest ""Karten"" als erste App in der zweiten Zeile haben. Oder Mail unten im Dock. Mit den anpassbaren Homescreens kannst du den iPod touch zu deinem iPod touch machen.
 
Individuelles Anpassen
Ordne die Symbole auf deinem Homescreen an wie du willst - direkt auf dem iPod touch oder auf deinem Computer in iTunes 9. Bewege eine App eine Zeile nach oben, zwei Apps nach rechts oder auf einen anderen Homescreen. Du kannst bis zu 11 Homescreens erstellen und hast so schnellen Zugriff auf Spiele und Apps, die du aus dem App Store lädst, und auf deine Safari Weblinks.
 
Hometaste
Was auch immer du gerade mit deinem iPod touch machst – die Hometaste bringt dich immer zurück zum ersten Homescreen. Wenn du auf die Hometaste drückst, kannst du von jedem Homescreen wieder zurück zum ersten springen.
 
Apps und Weblinks hinzufügen
Für jede App, die du aus dem App Store lädst, erscheint ein neues Symbol auf dem Homescreen. Von häufig besuchten Websites kannst du praktische Weblinks erstellen. Sie erscheinen auf dem Homescreen und du kannst per Fingertipp darauf zugreifen.
 
Spotlight Suche
Du suchst was? Von einem Ort aus kannst du die gesamten Inhalte des iPod touch durchsuchen. Streich auf dem ersten Homescreen einfach nach rechts, um Spotlight zu öffnen. Sobald du anfängst zu tippen, durchsucht Spotlight deine gesamten Songs, Videos, Kontakte, Mails, Kalender, Notizen und sogar deine Hörbücher und Podcasts.
 
Safari
Safari, der fortschrittlichste Webbrowser auf einem Mobilgerät, ist auch auf dem iPod touch integriert. Damit erlebst du das Internet in deiner Hand genauso wie auf dem Computer zuhause. Alles was du brauchst ist eine Wi-Fi-Verbindung.
 
Überall ins Internet
Der iPod touch ist der einzige iPod mit integriertem drahtlosen Internetzugriff. Bei bestehender Wi-Fi-Verbindung kannst du im Internet surfen und Nachrichten lesen, Sportergebnisse sehen, Rechnungen bezahlen und online einkaufen. Und beim 32 GB oder 64 GB iPod touch wirst du sehen, dass Webseiten jetzt noch schneller als vorher geladen werden.
 
Im Web stöbern
Der iPod touch synchronisiert deine Lesezeichen vom PC oder Mac, sodass du ruckzuck auf deine Lieblingsseiten zugreifen kannst. Außerdem ist die Google- und Yahoo!-Suche schon integriert, sodass du im Web schnell findest, was du suchst.
 
Weblinks
Wenn du eine Website öfter besuchst - etwa die einer Zeitung, eines Blogs oder eine Sport-Website - kannst du einfach ein Symbol, einen sogenannten Weblink, auf dem Homescreen erstellen. Wenn du mit Safari Weblinks erstellst, sind deine Lieblingsseiten nur einen Fingertipp entfernt.
 
Zoom
Wenn du eine Website öfter besuchst, brauchst du nur mit dem Finger auf das Multi-Touch-Display zu tippen oder die Anzeige aufzuziehen. Websites lassen sich im Hoch- oder Querformat anzeigen. Einfach den iPod touch um 90 Grad drehen, und schon wird auch die Darstellung der Webseite gedreht.
 
Mail
Mails auf dem iPod touch funktionieren genau wie auf deinem Computer und sehen auch genau so aus. Und sie funktionieren mit deinen vorhandenen Accounts.
 
Nachrichten und Anhänge ansehen
Der iPod touch unterstützt Rich-HTML-E-Mail, sodass Bilder und Fotos zusammen mit dem Text einer E-Mail angezeigt werden. Anhänge siehst du in ihrem Originalformat und nicht als abgespeckte Version. Du kannst in mehr als einem Dutzend standardmäßigen Datei- und Bildformaten drehen, zoomen und schwenken, darunter PDF, Microsoft Word, Excel, PowerPoint und iWork.
 
Zugriff auf alle Accounts
Mails von gängigen Anbietern wie MobileMe, Google Mail, Microsoft Exchange, Yahoo! und den meisten standardmäßigen IMAP- und POP-Systemen kannst du mit dem iPod touch ganz einfach abrufen.
 
Schnellere Eingabe
Der iPod touch erkennt E-Mail-Adressen in verschiedenen Programmen. Wenn du auf einer Webseite oder in einer Karte eine E-Mail-Adresse siehst, reicht ein Fingertipp auf dem iPod touch, um eine neue Mail zu öffnen, in der die Adresse bereits eingetragen ist.
 
Intelligente Eingabe
Die innovative iPod touch Tastatur mit integriertem Wörterbuch* schlägt während der Eingabe Wörter vor. So kannst du ganz schnell und einfach Mails schreiben. Dreh den iPod touch einfach. Dann wird die Tastatur vom Hochformat ins Querformat gedreht und du hast größere Tasten und mehr Platz zum Tippen.
 
Postfach durchsuchen
Du musst das Postfach jetzt nicht mehr Mail für Mail durchsuchen. Durch schnelles Abwärtsstreichen wird jetzt ein Suchfeld geöffnet, mit dem du deine Mails nach Absender, Empfänger, Betreff oder Titelzeilen durchsuchen kannst.
 
Karten
Finde deinen Weg und die nächste Pizzeria. Mit Karten und einer Wi-Fi-Verbindung kannst du Wegbeschreibungen abrufen, Firmen finden und Verkehrsinformationen prüfen.
 
Finde dich selbst
Der iPod touch zeigt dir mithilfe von bekannten Wi-Fi-Hot-Spots, wo du bist. Mit der Stichwortsuche kannst du auch interessante Orte finden. Wenn du z. B. ""Kaffee"" eingibst, werden dir alle Cafés in der Nähe angezeigt.
 
Wo geht's lang?
Gib einfach eine Adresse ein, um Wegbeschreibungen abzurufen - von jedem Ort aus. Wähle das Transportmittel wie Auto, öffentliches Verkehrsmittel oder zu Fuß. Die Route lässt sich dann Schritt für Schritt anzeigen. Du kannst dem markierten Weg auf der Karte folgen und selbst die Fahrtdauer wird angezeigt. Oder markiere zwei Orte und lass dir die beste Route zwischen diesen anzeigen.
 
Verschiedene Kartendarstellungen
Wie bei Google Karten auf deinem Computer kannst du mit dem Programm ""Karten"" auf dem iPod touch zwischen unterschiedlichen Darstellungen von Google-Karten, Satellitenbildern und einer Hybriddarstellung wechseln. Und mit Multi-Touch kannst du unterwegs zoomen, den Ausschnitt bewegen und die Darstellung ändern.
 
Verkehrsinformationen
Die Verkehrsinformationen geben dir anhand der grünen, roten und gelben Markierungen einen Überblick über die Verkehrssituation auf deiner Route.
 
YouTube
Skateboard Moves, die so nicht geplant waren. Witzige Werbespots aus anderen Ländern. Was auch immer du gern auf YouTube ansiehst - der iPod touch ist für dich da.
 
Videogrüße von unterwegs.
Maile Links deiner Lieblingsvideos an Freunde. Tippe auf der Detailseite des YouTube Videos auf ""Senden"", und schon erstellt der iPod touch eine Mail mit dem zugehörigen Videolink.
 
Auf YouTube suchen.
Stöber in Videokategorien wie ""Highlights"", ""Topvideos"", ""Neue Videos"" oder ""Bestwertung"". Du kannst auch per Schlagwort nach einem Video suchen. Etwas Passendes gefunden? Mit einem Lesezeichen kannst du das Video auch vormerken und später ansehen.
 
Nike + iPod Kompatibilität
Rock dein Training. Der iPod touch hat eine integrierte Unterstützung für Nike + iPod. Das ist Musik und Motivation in einem.
Finetuning für dein Lauftraining.
 
Nike + iPod Sensor
Der iPod touch hat eine integrierte Unterstützung für Nike + iPod. Einfach den Nike + iPod Sensor (separat erhältlich) in die Nike+ Schuhe stecken und los geht's. Der Sensor überträgt deine Laufdaten drahtlos an den iPod touch und zeichnet Laufzeit, Laufstrecke und Kalorienverbrauch auf. Du erhältst sogar Feedback zum Trainingsfortschritt.
 
Finetuning für dein Cardio Workout
Diese Funktion kann auch zusammen mit neuen, in vielen Fitnessstudios vorhandenen Geräten für das Ausdauertraining gekoppelt werden. Such dir einfach ein mit Nike + iPod kompatibles Fitnessgerät wie beispielsweise Laufbänder, Ellipsentrainer, Stepper und Hometrainer.
 
Synchronisieren mit nikeplus.com
Später kannst du am Computer den iPod touch via iTunes synchronisieren und deine Trainingsdaten an nikeplus.com übertragen. Auf dieser Website kannst du dein Training verfolgen, dir Ziele setzen und deine Freunde herausfordern.
 
Sprachmemos
Du hast vielleicht ein ganz gutes Gedächtnis, aber manchmal ist es besser, kleine (und große) Infos einfach irgendwo festzuhalten. Mit ""Sprachmemos"" kein Problem.
 
Memos (oder alles andere)aufnehmen
Nimm eine Aufgabenliste, geniale Ideen oder eine Wette zwischen dir und deinem Freund auf. Mit dem Programm ""Sprachmemos"" kannst du über die Apple Earphones mit Fernbedienung und Mikro oder ein externes Mikrofon aufnehmen, was immer du willst. Sprachmemos kannst du selbst dann aufnehmen, wenn du den iPod touch gerade verwendest, um Mails zu checken oder im Web zu surfen.
 
Memos bearbeiten
Aufgenommene Memos kannst du direkt auf dem iPod touch trimmen. So behältst du nur das, was du wirklich brauchst.
 
Memos sortieren
Ordne deine Memos mithilfe von Etiketten aus einer vordefinierten Liste oder erstelle eigene Etiketten.
 
Memos teilen
Maile Memos an Freunde und Kollegen. Mit dem iPod touch aufgenommene Memos werden via iTunes mit deinem Mac oder PC synchronisiert, damit du sie später mit anderen teilen kannst.
 
Weitere Funktionen
Auf dem iPod touch ist die neueste Software schon installiert. Und außerdem gibt's praktische Apps wie Kontakte, Kalender, Notizen, Aktien und Wetter.
 
iPod touch 3.1 Softwarefunktionen.
 
Genius Mixe
Diese neue Funktion ist wie ein privater DJ, der deine iTunes Mediathek durchsucht, um Songs zu finden, die gut zusammenpassen und aus diesen dann tolle Mixe erstellt. Alles ganz automatisch.
 
Genius Empfehlungen für Apps
Im App Store gibt's zehntausende Apps. Wie soll man da die richtig collen neuen finden? Mit Genius. Denn Genius sieht sich die Apps an, die du schon hast, und empfiehlt dir weitere.
 
Peer-to-Peer-Spiele
Die neusten Spiele kannst du ganz leicht mit Freunden spielen - egal, ob sie neben dir oder in einer anderen Ecke des Landes sitzen.
 
Kauf Filme, Fernsehsendungen und Hörbücher via Wi-Fi
Lade via Wi-Fi Filme, Fernsehsendungen, Musikvideos und Hörbücher aus dem iTunes Store auf deinen iPod touch.
 
Tastatur im Querformat
Du brauchst mehr Platz zum Tippen? Dreh den iPod touch ins Querformat, um in Mail, Notizen und Safari mit einer größeren Tastatur zu arbeiten.
 
Cut, Copy & Paste
Einfach Text und Fotos ausschneiden, kopieren und wieder einsetzen - selbst zwischen Programmen. Du kannst auch Inhalte aus dem Web kopieren.
 
Spotlight Suche
Gesucht, gefunden - von einem Ort aus. Spotlight durchsucht alle deine Kontakte, E-Mails, Kalender und Notizen und auch alle Songs und Videos.
 
Stereo Bluetooth
Hör Musik und andere Audioinhalte drahtlos. Verbinde den iPod touch mit kompatiblen Bluetooth Stereokopfhörern.
 
Automatischer Wi-Fi-Login
Wenn du dich einmal bei einem Wi-Fi-Hotspot anmeldest, loggt der iPod touch sich beim nächsten Mal automatisch ein.
 
Shake to Shuffle
Schüttel den iPod kurz, und schon springt er nach dem Zufallsprinzip zu einem anderen Song in deiner Sammlung. Lass dich einfach überraschen.
 
Bedienungshilfen
Der neue iPod touch hat standardmäßig Bedienungshilfen integriert, mit denen auch Menschen mit Beeinträchtigungen alles, was der iPod touch zu bieten hat, erleben können. Alle Bedienungshilfen des iPod touch ansehen
 
Kindersicherung
Du entscheidest, welche Musik, Videos und Apps auf dem iPod touch für deine Kinder geeignet sind.
Der iPod touch hat auch die folgenden praktischen Apps:
 
Kalender
Das Programm ""Kalender"" funktioniert mit Yahoo!, Google, Microsoft Outlook, iCal, MobileMe und Microsoft Exchange ActiveSync für Unternehmen. Füge Termine hinzu, lass dich an Termine erinnern, und abonniere Kalender, damit du über Feiertage und Sportveranstaltungen auf dem Laufenden bleibst.
 
Kontakte
Namen, E-Mail-Adressen, Telefonnummern und mehr - immer zur Hand. Synchronisier Kontakte in iTunes auf dem Mac oder PC mit dem iPod touch. Neue Kontakte kannst du auch unterwegs mit einem einfachen Fingertipp hinzufügen.
 
Notizen
Schluss mit Papier und Bleistift. Mach dir mit ""Notizen"" auf dem iPod schnell eine Notiz, damit du wichtige Infos immer parat hast. Maile deine Gedanken mit der integrierten Mail-Funktion an dich oder andere.
 
Aktien
Die Aktien App auf dem iPod touch zeigt dir Börseninformationen für die Aktien, die dich interessieren. Wenn du nähere Details über eine Aktie brauchst, tipp auf ""Y!"", um im Handumdrehen Yahoo! Finance zu öffnen.
 
Wetter
Informier dich über das Wetter in der ganzen Welt oder zuhause. Füge die gewünschten Städte hinzu und zeige eine sechstägige Vorhersage für alle an. Tipp auf ""Y!"", um den Yahoo! Stadtführer zu öffnen, der dir zeigt, wo was los ist.
 
Rechner
Im Programm ""Rechner"" des iPod touch stecken gleich zwei Rechner. Im Hochformat kannst du ihn als einfachen Taschenrechner verwenden. Dreh den iPod touch ins Querformat, um aus ihm einen wissenschaftlichen Rechner zu machen.
 
iPod touch Technologie
Dank der revolutionären Hardwaretechnologie im iPod touch kannst du alle Funktionen mit Streichen, Tippen und Auf- oder Zuziehen steuern. Deswegen wirkt das Autorennen so echt. Deswegen kannst du das, was du eben im Café mitbekommen hast, sofort twittern. Und genau deswegen ist der iPod touch der beste iPod aller Zeiten.
 
Multi-Touch
Das Multi-Touch-Display besitzt einen Schutzfilm über der kapazitiven Sensorik, die Berührungen anhand elektrischer Felder erkennt. Diese Informationen werden an das darunterliegende LCD-Display übertragen. Dank der Software des iPod touch kannst du mit Cover Flow durch Alben stöbern, durch deine Fotos blättern, mit Auf- und Zuziehen Bildausschnitte von Websites zoomen und Spiele superpräzise steuern.
 
Beschleunigungssensor
Der iPod touch reagiert über einen integrierten Beschleunigungssensor auf Bewegungen. Dieser Sensor erkennt, wenn du deinen iPod touch ins Querformat drehst und verändert automatisch den Inhalt des Displays. Die Technologie des Beschleunigungssensors kommt besonders bei Spielen gut, denn damit bist du mitten im Spielgeschehen. Das ist perfekt für Autorennen, bei denen der ganze iPod zum Lenkrad wird, und Geschicklichkeitsspiele wie Rolando, bei denen du das Spiel mit deinen Bewegungen steuerst
 
Drahtlos
Der iPod touch hat eine integrierte Unterstützung für drahtlosen 802.11b/g Internetzugriff. Überall, wo es ein Wi-Fi-Netzwerk gibt, kommst du mit deinem iPod touch ins Internet. Im Café mailen. Am Flughafen im Web surfen. Spiele vom Sofa aus kaufen. Im iTunes Store stöbern und Musik kaufen und laden. Der iPod touch findet nahegelegene Wi-Fi-Hot-Spots, auch geschützte Netzwerke. Wenn du ein bestimmtes Netzwerk bisher noch nicht verwendet hast, Drahtlos Symbol musst du beim ersten Mal ein Kennwort eingeben, das sich der iPod touch dann merkt. Wenn du dann das nächste Mal in Reichweite dieses Netzwerks bist, loggt er sich automatisch ein.
 
Bluetooth
Bluetooth ist eine drahtlose Technologie, mit der du Geräte ohne lästige Kabel verwenden kannst. Was bedeutet das für den iPod touch? Du kannst jetzt mit dem iPod touch und Bluetooth Kopfhörern Musik hören, ganz egal, wo im Raum der iPod ist. Du kannst also auf dem Bett relaxen, während der iPod auf dem Schreibtisch aufgeladen wird. Bluetooth auf dem iPod touch eignet sich auch besonders für Peer-to-Peer-Spiele.
 
Design
Der iPod touch ist von außen genau so großartig wie von innen. Du brauchst nur einen in die Hand zu nehmen. Das Gehäuse des iPod touch ist gerade einmal 8,5 mm hoch. Das optische Glas auf der Vorderseite und die Rückseite aus poliertem Edelstahl geben ihm einen eleganten Touch und fühlen sich in der Hand einfach gut an. Schalte ihn ein und du wirst über das brillante 3,5"" Display einfach staunen. Der iPod touch ist die perfekte Kombination aus großartigem Design und revolutionärer Technologie - das perfekte Paket.
";2;False;0;;;Apple iPod Touch 8 GB schwarz mit integrierter WiFi Funktion;apple-ipod-touch-8-gb-schwarz-2;True;True;PD-01085;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;169.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40871,5555092593;44;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000434-apple-ipod-touch-64-gb-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000435-apple-ipod-touch-64-gb-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000436-apple-ipod-touch-64-gb-schwarz.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Samsung Galaxy S II (i9100) DualCore Smartphone schwarz;"Samsung Galaxy S II (i9100) DualCore Smartphone (10.9 cm (4.3 Zoll) Super-Amoled Plus Display, Android 2.3, 8 MP Full-HD Kamera, 2 MP Frontkamera) schwarz ";"
Samsung launcht mit dem Galaxy S II den Nachfolger des Bestsellers Galaxy S. Das Galaxy S II ist nicht nur das schlankste (8,49 mm), sondern dank des 1,2 GHz Dual-Core Prozessors auch das schnellste Smartphone seiner Klasse. Darüber hinaus besticht es durch ein 4,3"" Super Amoled Plus Touch-Display. Das Galaxy S II verwendet als Betriebssystem die aktuellste Android 2.3 Version – auch bekannt unter dem Namen Gingerbread. Die integrierte 8 Megapixel Kamera mit LED Blitz hält die schönsten Momente in erstklassiger Qualität fest – darüber hinaus ermöglicht die 2 Megapixel Frontkamera Video Telefonate in beeindruckender Qualität. Das Schreiben von E-Mails und SMS gelingt unkompliziert dank Swype®-Texteingabe. Zahlreiche aktuelle und nützliche Apps stehen im Android Market™ zum Download bereit. Die integrierte Google Maps Navigation™ führt ans gewünschte Ziel. AllShare, HD Video, Exchange ActiveSync und eine Vielzahl an weiteren Applikationen lassen keine Wünsche offen. Ein erstklassiges Zusammenspiel von Hardware und Funktionen leistet sein Übriges für ein ausgezeichnetes Nutzererlebnis auf höchstem Niveau!
 
4,27-Zoll SUPER AMOLED Plus
Bekennen Sie Farbe! Dieses brillante Display bietet den besten Farbumfang, ein hohes Kontrastverhältnis sowie ultimative Schärfe bei Bildern. Die bahnbrechende Verkürzung der Video-Reaktionszeit sorgt für ruckfreie Videowiedergabe. Die neue Technologie benötigt weniger Platz und Energie: Im Vergleich zum Vorgänger benötigt das Display 18% weniger Energie. Es ist damit eines der dünnsten, langlebigsten Smartphones am Markt.
 
Brillante Performance
Das Unmögliche ist möglich. Der Samsung Dual Core Application Prozessor ist die reaktionsschnelle Antwort im Bereich mobile Performance. Er bietet Multitasking in Hochgeschwindigkeit, schnelles Laden von Internetseiten, schnelle Reaktionszeiten, eine intuitive Benutzeroberfläche, blitzschnelle Bildbearbeitung und Spiele mit hoher Performance. Und mit der superschnellen Möglichkeit zum Encodieren und Decodieren, die alles im Bereich Videoaufzeichnung und -wiedergabe (1080p / 30fps) unterstützt, stellt er alle anderen Dual Core-Prozessoren in den Schatten. Problemloses Video- oder Musik-Streaming bekommt dank des schnellen Drahtlosstandards HSPA 21 Mbps einen großen Schub. Hervorragende Rechenleistung, herausstechende Performance.
 
Schlankes Design
Schlank, schlanker, GALAXY S II. Das Samsung GALAXY S II führt die Riege an – mit nur 8,49 mm und einem luxuriösen Design liegt es zudem gut in der Hand. Das GALAXY S II ist eines der schlanksten Smartphones und bietet außerdem HyperSkin für einen schönen Metall-Look mit einer fingerabdruckfreien und rutschfesten Akkuabdeckung.
 
Readers Hub
Lassen Sie Ihre Bücher zu Hause: Das Samsung GALAXY S II übernimmt diese Aufgabe. Stöbern Sie im Readers Hub in Ihrer Bücherei mit Klassikern oder suchen Sie in mehr als 2 Millionen Büchern die neusten Bestseller. Sie können auch 2.500 Magazine in 20 Sprachen und 1.600 Zeitungen in 47 Sprachen zur Lieferung einrichten. Mit klarem, deutlichem Text und der hohen Bedienerfreundlichkeit macht das Lesen Spaß: vergrößern, nur Text und Seitenansichten, Audiozugriff sowie schnelles Verteilen per E-Mail sind nur einige Funktionen. Glauben Sie an Bücher, beschränken Sie sich jedoch nicht nur auf Papier.
 
8-Megapixel-Kamera mit LED-Blitz
Immer gute Fotos. Der 8-Megapixel-Kamera mit Autofokus entgehen auch bei Action-Fotos keine Details. Machen Sie auch bei schlechten Lichtverhältnissen mit dem integrierten LED-Blitz wunderschöne und detaillierte Aufnahmen. Und dank der stark verbesserten Benutzeroberfläche von Android Gingerbread ist selbst schneller Szenenwechsel möglich. Wechseln Sie problemlos auf die 2-Megapixel-Kamera vorne, um Selbstporträts zu machen. Einfach immer gute Bilder.
 
Aufzeichnung & Wiedergabe in Full-HD
Werden Sie zum Star. Mit den Möglichkeiten zur Videoaufzeichnung des Samsung GALAXY S II können auch Sie zur Berühmtheit werden. Mit der 1080p Full-HD-Aufzeichnung ist jeder Moment ein potenzielles Meisterwerk in der Entstehung. Erfassen Sie die Action in hoher Auflösung und mit Dual Core-Geschwindigkeit und geben Sie Ihre HD-Aufzeichnungen mit bestechender Klarheit auf dem 4,3"" SUPER AMOLED Plus Display wieder.
 
Spracherkennung & Sprachübersetzung
Einfach Sprachbefehle nutzen. Tippen Sie nur doppelt auf die Home-Taste und steuern Sie das Samsung GALAXY S II mit ausgewählten Sprachbefehlen. Führen Sie wichtige Funktionen wie anrufen, Musik hören oder SMS schreiben mit einfachen Sprachbefehlen aus. Sie können auch Ihre Gedanken festhalten, sich selbst eine Notiz schreiben oder unterwegs sogar mit Google Voice Translation eine Übersetzung anfertigen. Galaxy S II kann Ihnen eingehende Nachrichten auch vorlesen.
 
Game Hub
Noch mehr Spielspaß. Über den Game Hub von Samsung GALAXY S II können Sie hochwertige Spiele herunterladen: 12 soziale Netzwerkspiele und 13 Prämiumspiele einschließlich Gameloft’s Let Golf 2 und Real Football 2011. Sie können nach Spielen und Informationen zu Neuerscheinungen suchen oder einfach nur spielen. Mit einem Beschleunigungsaufnehmer, einem magnetischen Sensor und Gyroskop-Sensor heben sich Spiele mit Hand- und Armbewegungen deutlich aus der Masse ab. Die kleinste Bewegung reicht bereits aus – das ist spannende Unterhaltung.
 
Social Hub
Mit dem Social Hub lassen sich Ihre Online-Kontakte besser organisieren und synchronisieren. Sammeln Sie Ihre Informationen aus E-Mails, SMS, IM und SNS in einem einheitlichen Posteingang – Interaktionen mit anderen sind so schneller und auf die von Ihnen gewünschte Art möglich.
 
Music Hub
Musik darf nicht fehlen. Der neue native Music-Player von Samsung bietet ein intuitives Wiedergabesystem zum Suchen, Entdecken, Anspielen, Kaufen und Herunterladen von Musikstücken für unterwegs. Die App bietet auch viele Informationen zum Kauf sowie Zugriff auf alle gewünschten Künstler, Liedtexte und Bewertungen. Sie können Empfehlungen für neue Songs abrufen und durch Bassverstärkung und 5.1 Kanal-Sound den Hörspaß noch mehr steigern.
 
Microsoft Exchange ActiveSync
Das Samsung GALAXY S II ist für sicheren Zugriff auf Unternehmensressourcen auf einem Microsoft Exchange Server optimiert, damit Sie in Bezug auf geschäftliche E-Mails, Terminplaner, Kontakte und Aufgabensynchronisation auf dem Laufenden sind. Das Handy bietet die umfangreichste mobile Implementierung von Exchange ActiveSync. Es bietet das sicherste Mobile Device Management unter den Smartphones und unterstützt die meisten Richtlinien und Einschränkungen unter den Android ActiveSync Clients und ermöglicht Kommunikation in Echtzeit mit Telefonen der Mitarbeiter, um Einstellungen per Fernzugriff zu konfigurieren, die Einhaltung der Richtlinien zu überwachen, die Sicherheit bei synchronisierten Daten zu gewährleisten und verwaltete Telefone zu sperren oder Daten zu löschen.
";2;False;0;;;Samsung Galaxy S II (i9100) DualCore Smartphone schwarz;samsung-galaxy-s-ii-i9100-dualcore-smartphone-schwarz;True;True;PD-01084;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;439.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40871,5057638889;76;5;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000172-samsung-galaxy-s-ii-i9100-dualcore-smartphone-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000173-samsung-galaxy-s-ii-i9100-dualcore-smartphone-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000174-samsung-galaxy-s-ii-i9100-dualcore-smartphone-schwarz.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Nokia N9 Smartphone schwarz;"Nokia N9 Smartphone (9,9 cm (3,9 Zoll) Display, 16GB, Touchscreen, 8 Megapixel Kamera) schwarz ";"
Nokia N9 Smartphone
Formatfüllender Touchscreen
Ein einzigartiges Smartphone mit formatfüllendem Touchscreen. Die gewölbte Oberfläche aus kratzfestem Glas geht nahtlos in das glatte, aus einem Block gefertigte Gehäuse über. Jedes Detail strahlt Innovation aus. Auf dem brillanten AMOLED-Touchscreen erscheint alles in lebendigen Farben und das gewölbte Glas macht den Wechsel zwischen Apps per Fingerbewegung zum Kinderspiel.
 
Einfach nur eine Fingerbewegung - Überzeugend benutzerfreundlich
Alles läuft auf eine einfache Fingerbewegung hinaus. Das macht die Nutzung dieses Smartphones so intuitiv wie nie zuvor. Es gibt keine Zurück- oder Menü-Taste mehr – nur fliessende Fingerbewegungen, während Sie von App zu App wechseln. Mit einer Fingerbewegung über eine beliebige Ecke des Touchscreens gelangen Sie zur Startansicht, mit einer weiteren Bewegung wechseln Sie zwischen den drei Startansichten.
 
Eine Startansicht - Drei einfache Ansichten
Drei Ansichten sind alles, was Sie brauchen. In der vertrauten App-Ansicht starten Sie Anwendungen, eine weitere Ansicht zeigt die offenen Apps und macht Multitasking zum Kinderspiel: Sie machen genau dort weiter, wo Sie aufgehört haben.- Die Ansicht ""Ereignisse"" bringt Sie jederzeit auf den neuesten Stand der Dinge. Live-Feeds von Facebook und Twitter, E-Mails in Echtzeit, RSS-Feeds und mehr – alles an einer Stelle.
 
Karten und Navigation kostenlos
Live-Feeds von Facebook und Twitter, E-Mails in Echtzeit, RSS-Feeds und mehr – alles an einer Stelle. Sie finden die besten Angebote in Ihrer Stadt wie Cafés, Geschäfte, Konzerte, Hotels und mehr. Für mehr als 80 Städte weltweit steht Ihnen eine Übersicht von Strecken und Haltestellen des öffentlichen Nahverkehrs zur Verfügung. Entsprechendes Kartenmaterial ist bereits vorinstalliert, sodass Sie sofort starten können. Die Anwendung ""Fahren"" ist dank einfacher Bedienung über Touchscreen für die Verwendung im Auto optimiert.
 
Browser der nächsten Generation
Zeit für mehr Tempo. Das Nokia N9 bietet einen schnellen mobilen Internet-Browser und Seiten werden in kürzester Zeit aufgebaut. Die Unterstützung für HTML5 bedeutet für Sie das Beste aus dem Web, inklusive interaktiver Apps und schneller Videowiedergabe. Der Browser reagiert schnell auf jede Berührung. Sie können mehrere Seiten gleichzeitig öffnen und schnell zwischen den Seiten wechseln.
 
 
 
8-Megapixel-Kamera mit Optik von Carl Zeiss
Die Gelegenheit für ein gutes Foto kommt schnell und ist ebenso schnell vorbei. Mit der integrierten 8-Megapixel-Kamera mit Optik von Carl Zeiss können Sie brillante Fotos oder Videos in herausragender HD-Qualität aufnehmen.
 
Die besten Apps und Spiele
Apps sind heutzutage allgegenwärtig. Das Wichtigste ist jedoch die Qualität und nicht, wie viele man besitzt. Auf dem Nokia N9 sind die besten Apps wie Skype, Facebook, Twitter, AccuWeather und AP Mobile bereits vorinstalliert. Auch die Vollversion von Angry Birds ist bereits vorinstalliert – für viele Stunden Spass. Und im Ovi Store gibt es viele weitere Apps und Spiele.
";2;False;0;;;Nokia N9 Smartphone schwarz;nokia-n9-smartphone-schwarz;True;True;PD-01083;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;539.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40871,4967013889;74;17;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000164-nokia-n9-smartphone-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000165-nokia-n9-smartphone-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000166-nokia-n9-smartphone-schwarz.jpg;3;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Nokia N9 Smartphone magenta;Nokia N9 Smartphone (9,9 cm (3,9 Zoll) Display, 16GB, Touchscreen, 8 Megapixel Kamera) magenta;"
Nokia N9 Smartphone
Formatfüllender Touchscreen
Ein einzigartiges Smartphone mit formatfüllendem Touchscreen. Die gewölbte Oberfläche aus kratzfestem Glas geht nahtlos in das glatte, aus einem Block gefertigte Gehäuse über. Jedes Detail strahlt Innovation aus. Auf dem brillanten AMOLED-Touchscreen erscheint alles in lebendigen Farben und das gewölbte Glas macht den Wechsel zwischen Apps per Fingerbewegung zum Kinderspiel.
 
Einfach nur eine Fingerbewegung - Überzeugend benutzerfreundlich
Alles läuft auf eine einfache Fingerbewegung hinaus. Das macht die Nutzung dieses Smartphones so intuitiv wie nie zuvor. Es gibt keine Zurück- oder Menü-Taste mehr – nur fliessende Fingerbewegungen, während Sie von App zu App wechseln. Mit einer Fingerbewegung über eine beliebige Ecke des Touchscreens gelangen Sie zur Startansicht, mit einer weiteren Bewegung wechseln Sie zwischen den drei Startansichten.
 
Eine Startansicht - Drei einfache Ansichten
Drei Ansichten sind alles, was Sie brauchen. In der vertrauten App-Ansicht starten Sie Anwendungen, eine weitere Ansicht zeigt die offenen Apps und macht Multitasking zum Kinderspiel: Sie machen genau dort weiter, wo Sie aufgehört haben.- Die Ansicht ""Ereignisse"" bringt Sie jederzeit auf den neuesten Stand der Dinge. Live-Feeds von Facebook und Twitter, E-Mails in Echtzeit, RSS-Feeds und mehr – alles an einer Stelle.
 
Karten und Navigation kostenlos
Live-Feeds von Facebook und Twitter, E-Mails in Echtzeit, RSS-Feeds und mehr – alles an einer Stelle. Sie finden die besten Angebote in Ihrer Stadt wie Cafés, Geschäfte, Konzerte, Hotels und mehr. Für mehr als 80 Städte weltweit steht Ihnen eine Übersicht von Strecken und Haltestellen des öffentlichen Nahverkehrs zur Verfügung. Entsprechendes Kartenmaterial ist bereits vorinstalliert, sodass Sie sofort starten können. Die Anwendung ""Fahren"" ist dank einfacher Bedienung über Touchscreen für die Verwendung im Auto optimiert.
 
Browser der nächsten Generation
Zeit für mehr Tempo. Das Nokia N9 bietet einen schnellen mobilen Internet-Browser und Seiten werden in kürzester Zeit aufgebaut. Die Unterstützung für HTML5 bedeutet für Sie das Beste aus dem Web, inklusive interaktiver Apps und schneller Videowiedergabe. Der Browser reagiert schnell auf jede Berührung. Sie können mehrere Seiten gleichzeitig öffnen und schnell zwischen den Seiten wechseln.
 
 
 
8-Megapixel-Kamera mit Optik von Carl Zeiss
Die Gelegenheit für ein gutes Foto kommt schnell und ist ebenso schnell vorbei. Mit der integrierten 8-Megapixel-Kamera mit Optik von Carl Zeiss können Sie brillante Fotos oder Videos in herausragender HD-Qualität aufnehmen.
 
Die besten Apps und Spiele
Apps sind heutzutage allgegenwärtig. Das Wichtigste ist jedoch die Qualität und nicht, wie viele man besitzt. Auf dem Nokia N9 sind die besten Apps wie Skype, Facebook, Twitter, AccuWeather und AP Mobile bereits vorinstalliert. Auch die Vollversion von Angry Birds ist bereits vorinstalliert – für viele Stunden Spass. Und im Ovi Store gibt es viele weitere Apps und Spiele.
";2;False;0;;;Nokia N9 Smartphone magenta;nokia-n9-smartphone-magenta;True;True;PD-01082;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;549.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40871,4934027778;"74;2095";17;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000655-nokia-n9-smartphone-magenta.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000656-nokia-n9-smartphone-magenta.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000657-nokia-n9-smartphone-magenta.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Apple iPhone 4S weiß ";Apple iPhone 4S weiß;"
Das neue iPhone 4S - jetzt mit Dual Core A5 Chip, neuer 8 MegaPixel-Kamera, iOS 5 und iCloud sowie dem neuen Siri.
 
Dual-Core A5 Chip. Der leistungsstärkste iPhone Prozessor aller Zeiten.
Mit zwei Prozessorkernen liefert der A5 Chip bis zu 2x mehr Leistung und bis zu 7x schnellere Grafik. Das wirst du merken. Und zwar schnell. Das iPhone 4S reagiert extrem schnell, was du sofort merkst, wenn du Apps öffnest, im Web surfst, beim Spielen und auch bei allem anderen. Und ganz egal was du machst, du kannst es richtig lange machen. Denn der A5 Chip ist so effizient, dass das iPhone 4S eine enorm lange Batterielaufzeit hat.
 
Die Kaum-zu-glauben-dass-es-ein-Handy-ist Kamera.
Wahrscheinlich die beste Kamera, die es je auf einem Telefon gab. Und dank fortschrittlichster Optik ist sie wahrscheinlich auch die einzige Kamera, die du brauchst. Schließlich hat sie eine Auflösung von 8 Megapixeln und eine spezielle Linse mit einer größeren f/2,4 Blende. Außerdem bietet sie einen optimierten rückwärtig belichteten Sensor, exzellenten Weißabgleich, verbesserte Farbgenauigkeit, Gesichtserkennung und reduzierte Bewegungsunschärfe. Es ist also ganz egal, wie viele Leute, wie viel Licht und wie viel Action du aufnimmst – alles sieht genau so aus, wie es aussehen soll. Und warte erst, bis du die Fotos siehst.
 
Siri. Dein intelligenter, hilfsbereiter Assistent.Du musst ihn nur fragen.
Jetzt kannst du dein iPhone einfach mit deiner Stimme benutzen. Sprich mit Siri so, wie du mit einer Person sprichst und sag ""Erinnere mich daran, Mama anzurufen, wenn ich zu Hause bin"" oder ""Brauche ich einen Schirm?"". Siri spricht Deutsch und versteht nicht nur, was du sagst, sondern auch was du meinst. Es erkennt, welche Apps für die richtige Antwort nötig sind. Und antwortet dir dann – wie dein persönlicher Assistent. Siri telefoniert, sendet Nachrichten, plant Meetings, legt Erinnerungen fest und mehr. Was noch? Frag einfach, und Siri sagt es dir selbst.
 
Videoaufnahmen. In fantastischem 1080p HD.
Nimm fantastische 1080p HD Videos auf, wo immer du bist. Durch die neue fortschrittliche Optik der Kamera ist das Licht immer genau richtig, die Farben immer leuchtend und alles sieht noch besser aus, als du es in Erinnerung hattest. Die Bildstabilisierung gleicht verwackelte Aufnahmen aus. Und du kannst Videos direkt auf dem iPhone bearbeiten und so schnell mit anderen teilen, wie du sie aufnimmst.
 
iOS. Das fortschrittlichste mobile Betriebssystem der Welt. Und auch das einfachste.
Jede neue iOS Version bietet Möglichkeiten, die alles noch einfacher machen. Deshalb ist iOS allen anderen um Jahre voraus. Und iOS 5 geht wieder einen großen Schritt weiter und bringt mehr als 200 neue Features auf das iPhone 4S. Hier sind nur einige unserer Favoriten.
 
iCloud. Deine Inhalte. Auf all deinen Geräten.
Mit iCloud kannst du deine Inhalte ganz einfach verwalten, denn iCloud erledigt alles für dich. iCloud speichert deine Musik, Fotos, Apps, Mails, Kontakte, Kalender, Dokumente und mehr und pusht alles drahtlos an all deine Geräte. Automatisch, nahtlos und einfach so.
 
Retina Display.Das ist ganz klar.
Auf dem iPhone 4S siehst du einfach alles gestochen scharf und lebendig. Das Retina Display ist das höchstauflösende Telefondisplay aller Zeiten. Die Pixeldichte ist so hoch, dass das menschliche Auge keine einzelnen Pixel erkennen kann. Was du aber ganz bestimmt siehst, sind gestochen scharfe Texte, Grafiken und Bilder. Alles sieht sogar noch besser aus als gedruckt.
 
FaceTime. Wink doch mal hallo.
Mit FaceTime hörst du nicht nur eine Stimme, sondern siehst auch das Gesicht dazu – von iPhone zu iPhone, iPad 2, iPod touch oder Mac über Wi-Fi. Es ist also ganz egal, wo die anderen sind und wo du bist – du bist immer da. FaceTime Anrufe sind so einfach wie ganz normale Anrufe. Und mit Siri sind sie sogar noch einfacher. Sag Siri einfach, dass du mit deiner Mutter facetimen willst, und schon seht ihr euch. Einfach so. Du verpasst nie wieder ein wichtiges Ereignis, Meeting oder einen guten Lacher. Und wer würde sich nicht darüber freuen, dich zu sehen?
 
AirPlay. Live vom iPhone auf deinen Fernseher.
Mit AirPlay kannst du Inhalte von deinem iPhone via Apple TV drahtlos an deinen HD Fernseher und Lautsprecher streamen.6 Und mit der AirPlay Synchronisierung erscheint alles, was du auf deinem iPhone siehst oder machst, gleichzeitig auf deinem HD Fernseher.
 
AirPrint.Alles drahtlos drucken.
Drucke deine Mails, Fotos, Webseiten und Dokumente einfach über Wi-Fi von deinem iPhone aus.7 Ganz ohne Software zu laden, Treiber zu installieren oder Kabel anzuschließen. Nur ein paar Fingertipps und schon hast du das, was eben noch auf dem iPhone war, als Ausdruck in der Hand.
 
Besser. Schneller. Weltweiter.
Das iPhone 4S ist das erste Telefon, das zum Übertragen und Empfangen intelligent zwischen zwei Antennen wechselt. So ist die Anrufqualität deutlich besser. Außerdem verdoppeln die Antennen die maximale HSDPA Datengeschwindigkeit auf 14,4 Mbit/s.8 Und das bedeutet schnellere Verbindungen, schnelleres Laden und Neuladen und schnellere Downloads. Das iPhone 4S ist ein Telefon für die ganze Welt. Du kannst es also fast überall verwenden. Ob GSM- oder CDMA-Standard spielt keine Rolle. Nutze es via Roaming in GSM-Netzen in 200 Ländern weltweit.
 
Integrierte Apps. Machen alles, damit du alles machen kannst.
Ganz Alltägliches erledigst du mit dem iPhone 4S auf ganz außergewöhnliche Weise. Mach fantastische Fotos und nimm HD Videos auf. Sieh Freunde und Familie mit FaceTime. Tauche auf dem Retina Display richtig ins Web ein. Check deine Mails. Sende Nachrichten. Lege Erinnerungen fest. Schau in deinen Kalender. Oder sag Siri einfach, wie es dir helfen soll. Siri findet dann selbst heraus, welche Apps es verwenden muss.
 
Aufgrund der sehr umfangreichen Leistungsmerkmale können wir Ihnen hier nur einen Auszug präsentieren. Die vollständigen Funktionsbeschreibungen inkl. einer Vielzahl von Videos entnehmen Sie bitte der Herstellerwebseite.
•Apple iPhone 4S
•115,2 x 58,6 x 9,3 mm klein und 140 g leicht
•Kapazität: 16 GB Flash-Laufwerk
•Kamera, Fotos und Video:
• 8.0 Megapixel Kamera
• Videoaufnahme, HD (1080p) bis zu 30 fps mit Audio
• Fotos und Videos in VGA-Qualität mit bis zu 30 fps mit der Kamera an der Vorderseite
• Fokussieren per Fingertipp für Videos und Fotos LED-Blitz
• Geotagging für Fotos und Videos
•Display:
• Retina Display
• 3,5""-Multitouch-Display (8,89 cm Diagonale)
• Auflösung von 960 x 640 Pixeln mit 326ppi
• Typisches Kontrastverhältnis: 800:1
• Fettabweisende Beschichtung an der Vorder- und Rückseite
• Unterstützung für die Anzeige mehrerer Sprachen und Zeichen gleichzeitig
•Stromversorgung und Batterie:
• Sprechdauer: bis zu 8 Std. mit 3G, bis zu 14 Std. mit 2G
• Standbydauer: bis zu 200 Std.
• Internetnutzung: bis zu 6 Std. mit 3G, bis zu 9 Std. mit Wi-Fi
• Videowiedergabe: bis zu 10 Std., Audiowiedergabe: bis zu 40 Std.
•Betriebssystem: iOS 5
•Mobilfunknetz und Wi-Fi:
• UMTS/HSDPA/HSUPA (850, 900, 1900, 2100 MHz)
• GSM/Edge (850, 900, 1800, 1900 MHz)
• Funktechnologie: 802,11b/g/n Wi-Fi (802.11 nur mit 2,4 GHz), Bluetooth 4.0
•GPS: Assisted GPS
•Digitaler Kompass
•Unterstützte Audioformate: AAC (8 bis 320 KBit/Sek.), Protected AAC (aus dem iTunes Store), HE-AAC, MP3 (8 bis 320 KBit/Sek.), MP3 VBR, Audible (Formate 2, 3, 4, Audible Enhanced Audio, AAX und AAX+), Apple Lossless, AIFF und WAV
•TV und Video: AirPlay Mirroring to Apple TV support at 720p, Video mirroring and video out support: Up to 1080p with Apple Digital AV Adapter or Apple VGA Adapter (adapters sold separately), Video out support at 576p and 480p with Apple Component AV Cable; 576i and 480i with Apple Composite AV Cable (cables sold separately)
•Unterstützte Videoformate: H.264 Video: bis zu 720p, 30 Bilder pro Sekunde, Main Level Profile Level 3.1 mit AAC-LC Audio bis zu 160 KBit/Sek., 48 kHz, Stereo-Audio in den Formaten .m4v, .mp4 und .mov; MPEG.4 Video: bis zu 2,5 MBit/Sek., 640 x 480 Pixel, 30 Bilder pro Sekunde, Simple Profile mit AAC-LC Audio bis zu 160 KBit/Sek., 48 kHz, Stereo-Audio in den Formaten .m4v, .mp4 und .mov; Motion JPEG (M-JPEG): bis zu 35 MBit/Sek., 1280 x 720 Pixel, 30 Bilder pro Sekunde, Audio im Format ulaw, PCM Stereo-Audio im Format .avi
•Sensoren:
• 3-Achsen-Gyrosensor
• Beschleunigungssensor
• Annäherungssensor
• Umgebungslichtsensor
 
Lieferumfang:
iPhone 4S, Apple Earphones mit Fernbedienung und Mikrofon, Dock Connector-auf-USB-Kabel, Dokumentation
";2;False;0;;;Apple iPhone 4S weiß;apple-iphone-4s-weiss;True;True;PD-01080;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,5000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;779.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40870,6516782407;71;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000646-apple-iphone-4s-weis.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000647-apple-iphone-4s-weis.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000648-apple-iphone-4s-weis.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"AVM FRITZ!Fon MT-F VoIP Dect-Telefon ";"AVM FRITZ!Fon MT-F Innovatives DECT-Telefon ";"
FRITZ!Fon MT-F: HD-Telefonie und komfortable Internetdienste mit DECT.
Telefonieren Sie mit dem Schnurlostelefon FRITZ!Fon MT-F in bestechender Qualität über das Internet und nutzen Sie komfortable Webdienste. Als intelligentes Telefon der neuesten DECT-Generation vereint das FRITZ!Fon den Komfort der schnurlosen Telefonie mit den Qualitäts- und Leistungsmerkmalen der Internettelefonie (VoIP) in einem Gerät.
 
Bei der Internettelefonie mit einem FRITZ!Fon wird durch HD-Telefonie (High Definition) ein brillantes, natürliches Klanggefühl erreicht. Sprache lässt sich mit dem FRITZ!Fon in ihrem gesamten Frequenzspektrum wiedergeben, was die Klangqualität von Festnetzverbindungen deutlich übertrifft.
 
FRITZ!Fon unterstützt die übertragung großer Bandbreiten. Dies ermöglicht neben HD-Telefonie auch die Nutzung komfortabler Internetdienste wie den Empfang von E-Mails, Podcasts, RSS-Feeds und Internetradio.
 
Die Steuerung von FRITZ!Box-Anwendungen am Handgerät bietet viel zusätzlichen Komfort. Und durch DECT-Eco wird Funkabstrahlung bei Nichtnutzung der Telefone verhindert.
 
Die FRITZ!Box-Modelle FRITZ!Box Fon WLAN 7390, 7320, 7270, 7240 sowie FRITZ!Box 6360 Cable stellen mit der integrierten DECT-Basisstation, mehreren Anrufbeantwortern und Telefonbüchern für bis zu 300 Einträge den idealen Partner für das FRITZ!Fon dar. Mit der umfangreichen Prozessor- und Speicherausstattung ist auch der Grundstein für neue Anwendungen gelegt. Denn das FRITZ!Fon ist lernfähig:
 
Als eines der ersten intelligenten Schnurlostelefone wird es auch künftig per Firmware-Updates aktualisiert und um neue Funktionen erweitert werden können.
 
Umfangreicher Komfort
Das FRITZ!Fon MT-F ist mit zahlreichen Komfortfunktionen ausgestattet. Dazu zählen Lauthören und Freisprechen in HD-Qualität sowie ISDN-Leistungsmerkmale wie Namensanzeige bei bekannten Rufnummern, Halten, Makeln, Anklopfen, Rufumleitung oder Dreierkonferenz. Die Internettelefonie in HD-Qualität lässt sich so in ihrem vollen Umfang und Komfort nutzen, ohne dass der Computer eingeschaltet sein muss.
 
FRITZ!Fon informiert zudem aktiv über unbeantwortete Anrufe, Nachrichten auf dem Anrufbeantworter und zeigt eingegangene E-Mails an. An der DECT-Basisstation der FRITZ!Box Fon WLAN 7390, 7320, 7270, 7240 oder FRITZ!Box 6360 Cable lassen sich bis zu 6 FRITZ!Fon-Handgeräte oder andere DECT-Telefone anmelden. Die Erstinstallation und individuelle Einstellungen erfolgen dabei bequem über einfache Assistenten.
 
FRITZ!Box als idealer Partner
Das FRITZ!Fon MT-F kann als Mobilteil an jeder DECT-Basisstation eingesetzt werden. Im Zusammenspiel mit der FRITZ!Box Fon WLAN 7390, 7320, 7270, 7240 oder FRITZ!Box 6360 Cable kann jedoch das volle Spektrum der Möglichkeiten beim Telefonieren und Surfen über das Internet ausgenutzt werden.
 
Die FRITZ!Box Fon WLAN 7390 zum Beispiel vereint eine bisher nicht erreichte Vielfalt in einem Gerät: VDSL- und ADSL-Unterstützung, DECT-Basisstation fürs schnurlose Telefonieren sowie WLAN N für die optimale Datenübertragung. über den Mediaserver sind gespeicherte Filme, Musik und Bilder auch bei ausgeschaltetem Computer im gesamten Netzwerk verfügbar. Darüber hinaus kann der Online-Speicher wie eine lokale Festplatte genutzt werden. So wird die FRITZ!Box Fon WLAN 7390 zur idealen Plattform für vernetzte Anwendungen wie IPTV, Video on Demand oder Mediastreaming.
 
Bedienung
- Einfach einschalten und Suchtaste auf FRITZ!Box drücken.
 
- Einfache Bedienung über intuitives Menü.
 
- Telefonbuch komfortabel über FRITZ!Box-Oberfläche einrichten und anzeigen.
 
- In FRITZ!Box integrierte Anrufbeantworter einfach am FRITZ!Fon MT-F einrichten und abhören.
 
- Blinkende Leuchtdiode signalisiert eingegangene Anrufe, neue Nachrichten auf dem Anrufbeantworter und neue E-Mails.
";2;False;0;;;AVM FRITZ!Fon MT-F;avm-fritzfon-mt-f-voip-dect-telefon;True;True;PD-01079;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;79.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40653,4526388889;20;34;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000643-avm-fritzfon-mt-f-voip-dect-telefon.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000644-avm-fritzfon-mt-f-voip-dect-telefon.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000645-avm-fritzfon-mt-f-voip-dect-telefon.jpg;3;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Apple iPhone 4 weiß;Apple iPhone 4 weiß;"
Produktbeschreibungen
- Retina Display, 3,5"" Multi-Touch-Widescreen-Display (8,89 cm Diagonale)
- 960 x 640 Pixel bei 326 ppi
- Kontrastverhältnis: 800:1
- Fettabweisende Beschichtung an der Vorder- und Rückseite
- Unterstützung für die Anzeige mehrerer Sprachen und Zeichen gleichzeitig
- UMTS/HSDPA/HSUPA
- GSM/EDGE
- 802.11b/g/n WLAN
- Bluetooth 2.1 + EDR
- Li-Ionen-Akku, Sprechdauer bis zu 14Std. (2G), Internet bis zu 10Std. (WLAN)
 
";2;False;0;;;Apple iPhone 4 weiß;apple-iphone-4-weiss;True;True;PD-01078;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;779.0000;779.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.5000;0.0000;0.0000;0.0000;40653,4446064815;71;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000641-apple-iphone-4-weis.png;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000642-apple-iphone-4-weis.png;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Apple iPhone 4 schwarz ";"Apple iPhone 4 schwarz ";"
Produktbeschreibungen
- Retina Display, 3,5" Multi-Touch-Widescreen-Display (8,89 cm Diagonale)
- 960 x 640 Pixel bei 326 ppi
- Kontrastverhältnis: 800:1
- Fettabweisende Beschichtung an der Vorder- und Rückseite
- Unterstützung für die Anzeige mehrerer Sprachen und Zeichen gleichzeitig
- UMTS/HSDPA/HSUPA
- GSM/EDGE
- 802.11b/g/n WLAN
- Bluetooth 2.1 + EDR
- Li-Ionen-Akku, Sprechdauer bis zu 14Std. (2G), Internet bis zu 10Std. (WLAN)
";2;False;0;;;"Apple iPhone 4 schwarz ";apple-iphone-4-schwarz;True;True;PD-01077;;;False;0;False;;False;False;0;False;0;1;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;2;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;639.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40653,4410763889;71;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000639-apple-iphone-4-schwarz.png;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000640-apple-iphone-4-schwarz.png;;1;;False;ounce;;;;False;False;False;;;;;False;;;;;; -5;0;True;Apple iPad 2 schwarz;Apple iPad 2. Generation schwarz;"
Kapazität
16-GB-Flash-Laufwerk
32-GB-Flash-Laufwerk
64-GB-Flash-Laufwerk

Abmessungen und Gewicht

•Höhe: 241,2 mm
•Breite: 185,7 mm
•Tiefe: 8,8 mm
•Gewicht: 601 g

•Höhe: 241,2 mm
•Breite: 185,7 mm
•Tiefe: 8,8 mm
•Gewicht: 613 g


Drahtlose Technologie und Funknetz

•Wi-Fi (802.11a/b/g/n)
•Bluetooth 2.1 + EDR Technologie
•Wi-Fi + 3G Modell: UMTS/HSDPA/HSUPA (850, 900, 1900, 2100 MHz); GSM/EDGE (850, 900, 1800, 1900 MHz)
•Nur Datentransfer
•Wi-Fi (802.11a/b/g/n)
•Bluetooth 2.1 + EDR Technologie
Weitere Infos zu Wi-Fi + 3G

Display

•9,7"" Multi-Touch Hochglanz-Widescreendisplay mit LED-Hintergrundbeleuchtung und IPS-Technologie (24,63 cm Diagonale)
•Auflösung von 1024 x 768 Pixeln bei 132 ppi
•Fettabweisende Beschichtung
•Unterstützung für die Anzeige mehrerer Sprachen und Zeichen gleichzeitig
 
Chip
Speziell entwickelter, hochleistungsfähiger 1 GHz Dual-Core Apple A5 SOC (System-on-a-Chip) mit niedrigem Stromverbrauch
 
Kamera, Fotos, Videoaufnahme

•Rückkamera: Videoaufnahme, HD (720p) bis zu 30 fps mit Audio, Fotokamera mit 5-fach Digitalzoom
•Frontkamera: Videoaufnahme, VGA mit bis zu 30 fps mit Audio, Fotokamera in VGA-Qualität
•Fokussieren per Fingertipp für Videos und Fotos
•Geotagging für Fotos und Videos via Wi-Fi
 
Stromversorgung und Batterie

•Integrierte wiederaufladbare Lithium-Polymer-Batterie mit 25 Wattstunden
•Bis zu 10 Stunden Surfen im Web mit Wi-Fi, Video- oder Musikwiedergabe
•Aufladen über das Netzteil oder einen USB Anschluss am Computer

•Integrierte wiederaufladbare Lithium-Polymer-Batterie mit 25 Wattstunden
•Bis zu 10 Stunden Surfen im Web mit Wi-Fi, Video- oder Musikwiedergabe
•Bis zu 9 Stunden Batterielaufzeit beim Surfen im Internet über das 3G Datennetzwerk
•Aufladen über das Netzteil oder einen USB Anschluss am Computer
 
Ein- und Ausgabe

•30-poliger Dock-Anschluss
•3,5 mm Stereo-/Kopfhöreranschluss (Minianschluss)
•Integrierter Lautsprecher
•Mikrofon

•30-poliger Dock-Anschluss
•3,5 mm Stereo-/Kopfhöreranschluss (Minianschluss)
•Integrierter Lautsprecher
•Mikrofon
•Fach für Micro-SIM-Karte (nur beim Wi-Fi + 3G Modell)
 
Sensoren

•3-Achsen-Gyrosensor
•Beschleunigungssensor
•Umgebungslichtsensor

•3-Achsen-Gyrosensor
•Beschleunigungssensor
•Umgebungslichtsensor
 
Ortungsfunktion

•Wi-Fi
•Digitaler Kompass

•Wi-Fi
•Digitaler Kompass
•Assisted GPS
•Mobilfunknetz
 
Audiowiedergabe

•Frequenzbereich: 20 Hz bis 20.000 Hz
•Unterstützte Audioformate: HE-AAC (V1 und V2), AAC (8 bis 320 Kbit/s), Protected AAC (aus dem iTunes Store), MP3 (8 bis 320 Kbit/s), MP3 VBR, Audible (Formate 2, 3, 4, Audible Enhanced Audio, AAX und AAX+), Apple Lossless, AIFF und WAV
•Maximale Lautstärke vom Benutzer festlegbar
•Dolby Digital 5.1 Surround Sound Durchschleifen mit Apple Digital AV Adapter (separat erhältlich)
 
TV und Video

•Unterstützung für Bildschirmsynchronisation und Videoausgabe: bis zu 1080p mit dem Apple Digital AV Adapter oder dem Apple VGA-Adapter (Kabel separat erhältlich)
•Unterstützung für die Videoausgabe mit 576p und 480p mit dem Apple AV-Kabel (Komponentenvideo), mit 576i und 480i mit dem Apple AV-Kabel (Composite-Video)
•Unterstützte Videoformate: H.264 Video: bis zu 720p, 30 Bilder pro Sekunde, Main Profile Level 3.1 mit AAC-LC Audio mit bis zu 160 Kbit/s, 48 kHz, Stereo-Audio in den Formaten .m4v, .mp4 und .mov; MPEG-4 Video: bis zu 2,5 Mbit/s, 640 x 480 Pixel, 30 Bilder pro Sekunde, Simple Profile mit AAC-LC Audio mit bis zu 160 Kbit/s, 48 kHz, Stereo-Audio in den Formaten .m4v, .mp4 und .mov; Motion JPEG (M-JPEG): bis zu 35 Mbit/s, 1280 x 720 Pixel, 30 Bilder pro Sekunde, Audio im Format .ulaw, PCM Stereo-Audio im Format .avi
 
Unterstützte
E-Mail Anhänge

Anzeigbare Dokumenttypen: .jpg, .tiff, .gif (Bilder); .doc und .docx (Microsoft Word); .htm und .html (Webseiten); .key (Keynote); .numbers (Numbers); .pages (Pages); .pdf (Vorschau und Adobe Acrobat); .ppt und .pptx (Microsoft PowerPoint); .txt (Text); .rtf (Rich Text Format); .vcf (Kontaktdaten); .xls und .xlsx (Microsoft Excel)

Sprachen

•Sprachunterstützung für Englisch (USA), Englisch (Großbritannien), Französisch (Frankreich), Deutsch, traditionelles Chinesisch, vereinfachtes Chinesisch, Niederländisch, Italienisch, Spanisch, Portugiesisch (Brasilien), Portugiesisch (Portugal), Dänisch, Schwedisch, Finnisch, Norwegisch, Koreanisch, Japanisch, Russisch, Polnisch, Türkisch, Ukrainisch, Ungarisch, Arabisch, Thailändisch, Tschechisch, Griechisch, Hebräisch, Indonesisch, Malaiisch, Rumänisch, Slowakisch, Kroatisch, Katalanisch und Vietnamesisch

•Tastaturunterstützung für Englisch (USA), Englisch (Großbritannien), Französisch (Frankreich), Französisch (Kanada), Französisch (Schweiz), Deutsch, traditionelles Chinesisch (Handschrift, Pinyin, Zhuyin, Cangjie, Wubihua), vereinfachtes Chinesisch (Handschrift, Pinyin, Wubihua), Niederländisch, Italienisch, Spanisch, Portugiesisch (Brasilien), Portugiesisch (Portugal), Dänisch, Schwedisch, Finnisch, Norwegisch, Koreanisch, Japanisch (Romaji, 10 Tasten), Japanisch (Kana), Russisch, Polnisch, Türkisch, Ukrainisch, Estnisch, Ungarisch, Isländisch, Litauisch, Lettisch, Flämisch, Arabisch, Thailändisch, Tschechisch, Griechisch, Hebräisch, Indonesisch, Malaiisch, Rumänisch, Slowakisch, Kroatisch, Bulgarisch, Serbisch (Kyrillisch/Lateinisch), Katalanisch, Vietnamesisch, Tibetisch, Mazedonisch und Cherokee
 
•Wörterbuchunterstützung (aktiviert Textvorhersage und automatische Korrektur) für Englisch (USA), Englisch (Großbritannien), Französisch, Deutsch, traditionelles Chinesisch, vereinfachtes Chinesisch, Niederländisch, Italienisch, Spanisch, Portugiesisch (Brasilien), Portugiesisch (Portugal), Dänisch, Schwedisch, Finnisch, Norwegisch, Koreanisch, Japanisch (Romaji), Japanisch (Kana), Russisch, Polnisch, Türkisch, Ukrainisch, Ungarisch, Litauisch, Flämisch, Arabisch, Thailändisch, Tschechisch, Griechisch, Hebräisch, Indonesisch, Malaiisch, Rumänisch, Slowakisch, Kroatisch, Katalanisch, Vietnamesisch und Cherokee

Bedienungshilfen

•Unterstützung für die Wiedergabe von Inhalten mit erweiterten Untertiteln
•VoiceOver Bildschirmlesetechnologie
•Bildschirmfüllender Zoom
•Anzeigeoption ""Weiß-auf-Schwarz""
•Mono-Audioausgabe
 
Umgebungsbedingungen

•Betriebstemperatur: 0 °C bis 35 °C
•Lagertemperatur: -20 °C bis 45 °C
•Relative Luftfeuchtigkeit: 5 % bis 95 %, nicht kondensierend
•Maximale Betriebshöhe: ca. 3.000 m über NN, ohne Druckausgleich
 
Voraussetzungen für Mac

•Mac mit USB 2.0 Anschluss
•Mac OS X 10.5.8 (oder neuer)
•iTunes 10.2 oder neuer empfohlen
(kostenlos ladbar unter www.itunes.com/de/download)
•iTunes Store Account
•Internetzugang
 
Voraussetzungen für Windows

•PC mit USB 2.0 Anschluss
•Windows 7, Windows Vista oder Windows XP Home oder Professional mit Service Pack 3 (oder neuer)
•iTunes 10.2 oder neuer empfohlen
(kostenlos ladbar unter www.itunes.com/de/download)
•iTunes Store Account
•Internetzugang
 
Lieferumfang

•iPad
•Dock Connector auf USB Kabel
•10W USB Power Adapter (Netzteil)
•Dokumentation
 
Umweltverträglichkeit

 
Das iPad steht exemplarisch für das Engagement von Apple in Sachen Umweltschutz. Die folgenden Merkmale des iPad tragen zu seiner geringeren Umweltbelastung bei:

•Arsenfreies Displayglas
•Frei von bromhaltigen Flammschutzmitteln
•Quecksilberfreies Display mit LED-Hintergrundbeleuchtung
•Ohne PVC
•Recycelbares Gehäuse aus Aluminium und Glas
";2;False;0;;;Apple iPad 2 schwarz;apple-ipad-2-schwarz;True;True;PD-01076;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;9300;False;False;0;1;1;0;False;1;10000;;False;False;False;False;479.0000;479.0000;499.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40653,4073263889;54;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000633-apple-ipad-2-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000634-apple-ipad-2-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000635-apple-ipad-2-schwarz.jpg;1;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Apple iPad 2 weiß;Apple iPad 2. Generation weiß;"
Kapazität
 
16-GB-Flash-Laufwerk
32-GB-Flash-Laufwerk
64-GB-Flash-Laufwerk

Abmessungen und Gewicht
 
•Höhe: 241,2 mm
•Breite: 185,7 mm
•Tiefe: 8,8 mm
•Gewicht: 601 g
 
•Höhe: 241,2 mm
•Breite: 185,7 mm
•Tiefe: 8,8 mm
•Gewicht: 613 g
 
 
Drahtlose Technologie und Funknetz

•Wi-Fi (802.11a/b/g/n)
•Bluetooth 2.1 + EDR Technologie
•Wi-Fi + 3G Modell: UMTS/HSDPA/HSUPA (850, 900, 1900, 2100 MHz); GSM/EDGE (850, 900, 1800, 1900 MHz)
•Nur Datentransfer
•Wi-Fi (802.11a/b/g/n)
•Bluetooth 2.1 + EDR Technologie
Weitere Infos zu Wi-Fi + 3G
 

Display

 
•9,7"" Multi-Touch Hochglanz-Widescreendisplay mit LED-Hintergrundbeleuchtung und IPS-Technologie (24,63 cm Diagonale)
•Auflösung von 1024 x 768 Pixeln bei 132 ppi
•Fettabweisende Beschichtung
•Unterstützung für die Anzeige mehrerer Sprachen und Zeichen gleichzeitig
 
 
Chip
Speziell entwickelter, hochleistungsfähiger 1 GHz Dual-Core Apple A5 SOC (System-on-a-Chip) mit niedrigem Stromverbrauch
 
 
Kamera, Fotos, Videoaufnahme
 
•Rückkamera: Videoaufnahme, HD (720p) bis zu 30 fps mit Audio, Fotokamera mit 5-fach Digitalzoom
•Frontkamera: Videoaufnahme, VGA mit bis zu 30 fps mit Audio, Fotokamera in VGA-Qualität
•Fokussieren per Fingertipp für Videos und Fotos
•Geotagging für Fotos und Videos via Wi-Fi
 
 
Stromversorgung und Batterie
 
•Integrierte wiederaufladbare Lithium-Polymer-Batterie mit 25 Wattstunden
•Bis zu 10 Stunden Surfen im Web mit Wi-Fi, Video- oder Musikwiedergabe
•Aufladen über das Netzteil oder einen USB Anschluss am Computer
 
•Integrierte wiederaufladbare Lithium-Polymer-Batterie mit 25 Wattstunden
•Bis zu 10 Stunden Surfen im Web mit Wi-Fi, Video- oder Musikwiedergabe
•Bis zu 9 Stunden Batterielaufzeit beim Surfen im Internet über das 3G Datennetzwerk
•Aufladen über das Netzteil oder einen USB Anschluss am Computer
 
 
Ein- und Ausgabe
 
•30-poliger Dock-Anschluss
•3,5 mm Stereo-/Kopfhöreranschluss (Minianschluss)
•Integrierter Lautsprecher
•Mikrofon
 
•30-poliger Dock-Anschluss
•3,5 mm Stereo-/Kopfhöreranschluss (Minianschluss)
•Integrierter Lautsprecher
•Mikrofon
•Fach für Micro-SIM-Karte (nur beim Wi-Fi + 3G Modell)
 
 
Sensoren
 
•3-Achsen-Gyrosensor
•Beschleunigungssensor
•Umgebungslichtsensor
 
•3-Achsen-Gyrosensor
•Beschleunigungssensor
•Umgebungslichtsensor
 
 
Ortungsfunktion
 
•Wi-Fi
•Digitaler Kompass
 
•Wi-Fi
•Digitaler Kompass
•Assisted GPS
•Mobilfunknetz
 
 
Audiowiedergabe
 
•Frequenzbereich: 20 Hz bis 20.000 Hz
•Unterstützte Audioformate: HE-AAC (V1 und V2), AAC (8 bis 320 Kbit/s), Protected AAC (aus dem iTunes Store), MP3 (8 bis 320 Kbit/s), MP3 VBR, Audible (Formate 2, 3, 4, Audible Enhanced Audio, AAX und AAX+), Apple Lossless, AIFF und WAV
•Maximale Lautstärke vom Benutzer festlegbar
•Dolby Digital 5.1 Surround Sound Durchschleifen mit Apple Digital AV Adapter (separat erhältlich)
 
 
TV und Video
 
•Unterstützung für Bildschirmsynchronisation und Videoausgabe: bis zu 1080p mit dem Apple Digital AV Adapter oder dem Apple VGA-Adapter (Kabel separat erhältlich)
•Unterstützung für die Videoausgabe mit 576p und 480p mit dem Apple AV-Kabel (Komponentenvideo), mit 576i und 480i mit dem Apple AV-Kabel (Composite-Video)
•Unterstützte Videoformate: H.264 Video: bis zu 720p, 30 Bilder pro Sekunde, Main Profile Level 3.1 mit AAC-LC Audio mit bis zu 160 Kbit/s, 48 kHz, Stereo-Audio in den Formaten .m4v, .mp4 und .mov; MPEG-4 Video: bis zu 2,5 Mbit/s, 640 x 480 Pixel, 30 Bilder pro Sekunde, Simple Profile mit AAC-LC Audio mit bis zu 160 Kbit/s, 48 kHz, Stereo-Audio in den Formaten .m4v, .mp4 und .mov; Motion JPEG (M-JPEG): bis zu 35 Mbit/s, 1280 x 720 Pixel, 30 Bilder pro Sekunde, Audio im Format .ulaw, PCM Stereo-Audio im Format .avi
 
 
Unterstützte
E-Mail Anhänge
 
Anzeigbare Dokumenttypen: .jpg, .tiff, .gif (Bilder); .doc und .docx (Microsoft Word); .htm und .html (Webseiten); .key (Keynote); .numbers (Numbers); .pages (Pages); .pdf (Vorschau und Adobe Acrobat); .ppt und .pptx (Microsoft PowerPoint); .txt (Text); .rtf (Rich Text Format); .vcf (Kontaktdaten); .xls und .xlsx (Microsoft Excel)
 
Sprachen
 
•Sprachunterstützung für Englisch (USA), Englisch (Großbritannien), Französisch (Frankreich), Deutsch, traditionelles Chinesisch, vereinfachtes Chinesisch, Niederländisch, Italienisch, Spanisch, Portugiesisch (Brasilien), Portugiesisch (Portugal), Dänisch, Schwedisch, Finnisch, Norwegisch, Koreanisch, Japanisch, Russisch, Polnisch, Türkisch, Ukrainisch, Ungarisch, Arabisch, Thailändisch, Tschechisch, Griechisch, Hebräisch, Indonesisch, Malaiisch, Rumänisch, Slowakisch, Kroatisch, Katalanisch und Vietnamesisch
 
•Tastaturunterstützung für Englisch (USA), Englisch (Großbritannien), Französisch (Frankreich), Französisch (Kanada), Französisch (Schweiz), Deutsch, traditionelles Chinesisch (Handschrift, Pinyin, Zhuyin, Cangjie, Wubihua), vereinfachtes Chinesisch (Handschrift, Pinyin, Wubihua), Niederländisch, Italienisch, Spanisch, Portugiesisch (Brasilien), Portugiesisch (Portugal), Dänisch, Schwedisch, Finnisch, Norwegisch, Koreanisch, Japanisch (Romaji, 10 Tasten), Japanisch (Kana), Russisch, Polnisch, Türkisch, Ukrainisch, Estnisch, Ungarisch, Isländisch, Litauisch, Lettisch, Flämisch, Arabisch, Thailändisch, Tschechisch, Griechisch, Hebräisch, Indonesisch, Malaiisch, Rumänisch, Slowakisch, Kroatisch, Bulgarisch, Serbisch (Kyrillisch/Lateinisch), Katalanisch, Vietnamesisch, Tibetisch, Mazedonisch und Cherokee
 
•Wörterbuchunterstützung (aktiviert Textvorhersage und automatische Korrektur) für Englisch (USA), Englisch (Großbritannien), Französisch, Deutsch, traditionelles Chinesisch, vereinfachtes Chinesisch, Niederländisch, Italienisch, Spanisch, Portugiesisch (Brasilien), Portugiesisch (Portugal), Dänisch, Schwedisch, Finnisch, Norwegisch, Koreanisch, Japanisch (Romaji), Japanisch (Kana), Russisch, Polnisch, Türkisch, Ukrainisch, Ungarisch, Litauisch, Flämisch, Arabisch, Thailändisch, Tschechisch, Griechisch, Hebräisch, Indonesisch, Malaiisch, Rumänisch, Slowakisch, Kroatisch, Katalanisch, Vietnamesisch und Cherokee
 
Bedienungshilfen
 
•Unterstützung für die Wiedergabe von Inhalten mit erweiterten Untertiteln
•VoiceOver Bildschirmlesetechnologie
•Bildschirmfüllender Zoom
•Anzeigeoption ""Weiß-auf-Schwarz""
•Mono-Audioausgabe
 
 
Umgebungsbedingungen 

•Betriebstemperatur: 0 °C bis 35 °C
•Lagertemperatur: -20 °C bis 45 °C
•Relative Luftfeuchtigkeit: 5 % bis 95 %, nicht kondensierend
•Maximale Betriebshöhe: ca. 3.000 m über NN, ohne Druckausgleich
 
 
Voraussetzungen für Mac
 
•Mac mit USB 2.0 Anschluss
•Mac OS X 10.5.8 (oder neuer)
•iTunes 10.2 oder neuer empfohlen
(kostenlos ladbar unter www.itunes.com/de/download)
•iTunes Store Account
•Internetzugang
 
 
Voraussetzungen für Windows
 
•PC mit USB 2.0 Anschluss
•Windows 7, Windows Vista oder Windows XP Home oder Professional mit Service Pack 3 (oder neuer)
•iTunes 10.2 oder neuer empfohlen
(kostenlos ladbar unter www.itunes.com/de/download)
•iTunes Store Account
•Internetzugang
 
 
Lieferumfang
 
•iPad
•Dock Connector auf USB Kabel
•10W USB Power Adapter (Netzteil)
•Dokumentation
 
 
Umweltverträglichkeit
 
 
Das iPad steht exemplarisch für das Engagement von Apple in Sachen Umweltschutz. Die folgenden Merkmale des iPad tragen zu seiner geringeren Umweltbelastung bei:
•Arsenfreies Displayglas
•Frei von bromhaltigen Flammschutzmitteln
•Quecksilberfreies Display mit LED-Hintergrundbeleuchtung
•Ohne PVC
•Recycelbares Gehäuse aus Aluminium und Glas
";2;False;0;;;Apple iPad 2 weiß;apple-ipad-2-weiss;True;True;PD-01075;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;479.0000;0.0000;499.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40653,4018865741;54;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000627-apple-ipad-2-weis.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000628-apple-ipad-2-weis.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000629-apple-ipad-2-weis.jpg;1;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Apple MacBook Pro MC721D/A 15,4 Zoll Notebook;"Apple MacBook Pro MC721D/A 39.1 cm (15,4 Zoll) Notebook (Intel Core i7 2635QM, 2 GHz, 4GB RAM, 500GB HDD, AMD 6490M, DVD, Mac OS) ";"
Apple MacBook Pro MC721D/A
Intel Core i7 2635QM, 2 GHz

Unibody-Gehäuse. Am Anfang jedes MacBook Pro steht ein Werkstück aus Aluminium.Stark, leicht und schön in einem.
Das MacBook Pro ist aus einem einzigen Aluminiumblock gefertigt - eine technische Meisterleistung, bei der viele Bauteile durch ein einziges ersetzt werden. Das Ganze nennt sich Unibody. Gleich beim ersten Mal, wenn Sie ein MacBook Pro in der Hand haben, werden Sie den Unterschied spüren. Das Gehäuse ist dünner und leichter als andere Notebooks. Es sieht elegant aus. Und es fühlt sich stabil und robust an: perfekt für die Aktentasche, den Rucksack und natürlich auch für draußen.
 
Ein Display voll brillanter Ideen.
Alles, was Apple Designer und Ingenieure tun, ist von A bis Z durchdacht. Sie entschieden sich beim MacBook Pro für die LED-Hintergrundbeleuchtung, weil das Display damit sofort seine volle Helligkeit erreicht und trotzdem unglaublich dünn ist. Sie verwendeten eine durchgehende Oberfläche aus Glas, nicht nur weil es schön aussieht, sondern weil es dem ganzen Display Struktur verleiht. Und über dem Bildschirm haben sie die neue, integrierte FaceTime HD Kamera versteckt. So siehst du Freunde und Familie im Großformat - und dabei so gut wie nichts von der Kamera.
 
Magnetverschluss
Da der magnetische Verschluss keine beweglichen Teile hat, die abbrechen können oder an denen man hängen bleibt, ist das Öffnen und Schließen so einfach wie alles beim MacBook Pro.
 
Einfach auf alle Anschlüsse zugreifen.
Alle Anschlüsse am MacBook Pro - der MagSafe Netzanschluss, der Gigabit Ethernetanschluss, der Thunderbolt Anschluss, der USB Anschluss, der Karten-Steckplatz und der Audioeingang und -ausgang - sind ganz auf einer Seite des Notebooks integriert. So bleiben die Kabel schön geordnet und Geräte lassen sich schnell und einfach anschließen und auch wieder trennen.
 
Hinterlässt Eindruck. Aber nicht auf die Umwelt.
Weil Apple die vollständige Kontrolle über Design, Fertigung und Verpackung des MacBook Pro hat, hat Apple einen Vorsprung beim Umweltschutz. Die Technologie zur Hintergrundbeleuchtung des Displays spart Energie. Glas und Aluminium sind besonders recyclingfähig. Das MacBook Pro kommt fast ohne Giftstoffe aus. Und die Verpackung des 39,11 cm / 15,4"" Modells ist im Vergleich zum Vorgängermodell 34 Prozent kleiner. Das bedeutet nicht nur, dass für die Verpackungen weniger Bäume gefällt werden, es werden für den Transport auch weniger Flugzeugen, Güterzügen und LKWs benötigt.
 
Thunderbolt AnschlussDie Grafikleistung, die Sie brauchen, wenn Sie sie brauchen.
Alle MacBook Pro Modelle haben jetzt einen integrierten Intel HD Graphics 3000 Prozessor für die täglichen Aufgaben. Er codiert Videos schnell, ermöglicht HD Videotelefonate mit FaceTime und vieles mehr. Und auch Decodieren erledigt er effizienter, was bedeutet, dass Sie richtig lange DVDs und iTunes Filme schauen können. Bei anspruchsvollen Grafikprogrammen wechseln die 39,11 cm / 15,4"" MacBook Pro Modelle automatisch den Grafikprozessor und arbeiten mit den neuen leistungsstarken AMD Radeon Grafikprozessoren. Diese bieten verglichen mit den Vorgängermodellen die bis zu 3-fache Leistung. So sehen Sie bei 3D Spielen mehr Bilder pro Sekunde oder können schneller als je zuvor an HD Videoprojekten arbeiten.
 
Das neue Thunderbolt. Die schnellste, vielseitigste I/O Technologie in einem Notebook.
Stellen Sie sich vor, Sie könnten auf deinem Notebook auf mehrere unkomprimierte HD Videostreams zugreifen - und zwar so schnell, dass Sie einen HD Spielfilm in Echtzeit schneiden können. Thunderbolt macht genau das möglich. Mit Thunderbolt lassen sich superschnelle Peripheriegeräte der nächsten Generation an die Computer der nächsten Generation anschließen - angefangen beim MacBook Pro. Die Thunderbolt Pipeline ist ultraschnell und ultraflexibel. Sie ist über 12 Mal schneller als FireWire 800 und bis zu 20 Mal schneller als USB 2.0. Und sie bietet beispiellose Erweiterungsmöglichkeiten. Kurzum: Sie verändert alles, was Sie auf Ihrem Notebook machen können. Der Thunderbolt Anschluss gibt Ihnen Plug&Play Anschluss für eine völlig neue Welt von Thunderbolt Peripheriegeräten sowie für das Apple LED Cinema Display und andere Mini DisplayPort Peripheriegeräte. Sie können bis zu sechs Thunderbolt Geräte in Reihenschaltung anschließen, darunter auch Ihr Display. Außerdem unterstützt Thunderbolt Video und Achtkanal-Audio, sodass es auch möglich ist, HDMI-kompatible Geräte wie Fernseher oder Stereoanlagen über einen HDMI-Adapter anzuschließen. Auch aktuelle VGA-, DVI- und DisplayPort Adapter werden unterstützt.
 
Die neue FaceTime HD Kamera. Der Unterschied ist ganz klar.
Sehen Sie mehr von Ihren Freunden mit dem HD Widescreenformat - und zwar gestochen scharf. Die neue FaceTime HD Kamera bietet die dreifache Auflösung der vorherigen Kamera, was perfekt für das brillante Display mit LED-Hintergrundbeleuchtung ist. Außerdem arbeitet sie jetzt bei schwachem Licht noch besser. Sie können mit Ihren Freunden HD Telefonate in 720p von einem neuen MacBook Pro zu einem anderen führen. Außerdem sind auch Videotelefonate zu anderen Macs mit Intel Prozessor, zum iPhone 4 oder zum neuen iPod touch möglich.
 
Multi-Touch Trackpad - Jede Menge Platz für GestenMulti-Touch Trackpad. Fürs tägliche Handwerk.
Mit dem Multi-Touch Trackpad interagieren Sie auf ganz natürliche Art mit den Inhalten auf deinem Display. Und die glatte Glasoberfläche bietet jede Menge Platz für Gesten. Durch Auf- und Zuziehen können Sie ein- und auszoomen, durch Streichen in deinen Fotos blättern, durch Drehen ein Bild anpassen und vieles mehr. Das Trackpad kommt ohne Taste aus, sodass Sie überall klicken können. Wenn Sie aus der Welt des rechten Mausklicks kommen, können Sie diesen entweder mit zwei Fingern auslösen, oder Sie konfigurieren einen physischen Rechtsklick-Bereich auf dem Trackpad. Je mehr Sie mit dem Multi-Touch Trackpad vertraut sind, desto mehr werden Sie sich fragen, wie Sie jemals ohne ausgekommen sind.
 
Lange Laufzeit. Weniger aufladen. Mehr machen.
Das neue MacBook Pro bietet eine fantastische Batterielaufzeit und das mit leistungsstärkeren Prozessoren und schnelleren Grafikprozessoren. Die energieeffiziente Prozessorarchitektur mit integriertem Video-Encoder sowie das automatische Umschalten zwischen den Grafikprozessoren bei den 39,11 cm / 15,4"" Modellen helfen, die Batterielaufzeit weiter zu verbessern. So können Sie pro Ladung bis zu 7 Stunden ohne Kabel im Web surfen oder es für Liveauftritte oder auf ein Shooting mitnehmen. Die fortschrittlichen chemischen Eigenschaften und die Adaptive Charging Technologie sorgen dafür, dass die Batterie bis zu 1000 Ladezyklen durchlaufen kann. Und da die Batterie des MacBook Pro bis zu fünf Jahre hält, kommt das MacBook Pro in einem Zeitraum, in dem ein herkömmliches Notebook drei Batterien verbraucht, mit nur einer aus. Das ist für die Benutzer genauso gut, wie für die Umwelt. Apple verwendet eine neue, strengere Testmethode, um zu messen, welche Ergebnisse Sie unter realen Bedingungen erzielen, z. B. beim Surfen in einem Cafe oder wenn Sie die neuesten Webvideos ansehen. Und wie schneidet dieses MacBook Pro dabei verglichen mit der Vorgängergeneration ab? Es liefert die gleiche fantastische Leistung.
 
Hat beste Verbindungen.
Unterwegs haben Sie mit der 802.11n Technologie im MacBook Pro immer Verbindung. Das MacBook Pro findet automatisch verfügbare Netzwerke und Sie können sich mit einem Klick verbinden. Auch die drahtlose Bluetooth Technologie ist integriert, sodass Sie drahtloses Zubehör sofort nach dem Auspacken verwenden können.
 
DVDs superschnell brennen.
Homevideos, die Sie mit iMovie und iDVD gemacht haben, können Sie mit dem 8-fach SuperDrive Laufwerk des MacBook Pro superschnell auf eine DVD brennen. Das SuperDrive kann auch Double-Layer-DVDs (also DVDs mit fast 9 GB Speicherplatz) beschreiben, sodass es auch hervorragend für Datensicherungen geeignet ist.
 
Neue Intel Core i7 Prozessoren.
Neue Quad-Core Intel Core i7 Prozessoren sind Standard beim 39,11 cm / 15,4"" MacBook Pro. Alle Modelle verwenden die kürzlich optimierten Chipsets von Intel. Was heißt das für die neuen MacBook Pro Modelle? Kurz gesagt: Sie sind bis zu zwei Mal schneller als die Vorgängergeneration und erledigen auch anspruchsvolle Aufgaben wie HD Videoschnitt, Audiokompilierung oder Rendering mehrschichtiger Bilddateien unglaublich schnell. Und da Mac OS X Snow Leopard darauf ausgelegt ist, jeden Prozessorkern zu nutzen, holt das Betriebssystem wirklich alles an Leistung aus dem Prozessor heraus.
 
Schnellere Einzelchip-Mikroarchitektur.
Ob Sie einen Film ansehen, Ihren Blog auf den neuesten Stand bringen oder Fotos bearbeiten - die Daten müssen von A nach B gelangen, um verarbeitet werden zu können. Die neueste Intel Core Architektur bringt den Prozessor, den Cache, den Speichercontroller und den Grafikprozessor auf einem einzigen Chip unter. Deswegen müssen die Daten keine weiten Wege zurücklegen, was für Sie schnellere Performance und höhere Effizienz bedeutet.
 
Turbo Boost 2.0.
Angenommen, Sie arbeiten mit einem prozessorintensiven Programm wie Aperture 3 oder Final Cut Pro, das von einem Leistungsschub profitiert würde. Turbo Boost ist eine dynamische Technologie, die automatisch die Geschwindigkeit der aktiven Prozessorkerne auf 3,4 GHz erhöht. Turbo Boost 2.0 ist noch dynamischer und effizienter. Es wechselt die Kernfrequenz in kleineren Schritten als bisher, sodass der Prozessor die Leistung ohne Effizienzeinbußen verwalten kann. All das passiert im Hintergrund. Sie arbeiten einfach nur schneller.
 
Hyper-Threading.
Hyper-Threading ist jetzt Standard auf jedem MacBook Pro. Mit dieser Technologie können auf jedem Kern zwei Threads gleichzeitig laufen, Mac OS X erkennt also bei einem Quad-Core Prozessor acht und bei einem Dual-Core Prozessor vier virtuelle Kerne. Wenn Sie mehrere Programme gleichzeitig verwenden, verteilt der Prozessor die Aufgaben gleichmäßiger über eine größere Anzahl Kerne.
 
Integrierter Speichercontroller.
Mit schnellerem Speicherzugriff legt jeder Kern direkt mit der Verarbeitung der Daten los, statt auf ihr Eintreffen zu warten. Genau deshalb nutzt die neue Intel Core Architektur einen integrierten Speichercontroller, der den schnellen 1333 MHz Speicher direkt mit dem Prozessor verbindet und Ihre Programme immer die maximale Prozessorleistung zur Verfügung haben.
 
Energieeffiziente Grafik.
Dank der neuen Mikroarchitektur ist der Grafikprozessor auf dem gleichen Chip wie der Zentralprozessor und hat direkten Zugriff auf den L3-Cache. Kurze Wege bedeuten mehr Leistung. Der Grafikprozessor erhöht auch automatisch die Taktrate für noch höhere Auslastung. Ein integrierter Video-Encoder ermöglicht jetzt HD Videotelefonate mit FaceTime, und der effiziente Decoder sorgt für lange Batterielaufzeit, wenn Sie sich DVDs oder iTunes Filme ansiehen.
 
Mac OS X. Das fortschrittlichste Betriebssystem der Welt.
Mac OS X ist das Herz jedes MacBook Pro und Mac. Dieses Betriebssystem ist genau auf die integrierten Intel Multicore-Prozessoren und fortschrittlichen Grafikprozessoren zugeschnitten. Die neueste Version, Mac OS X Snow Leopard, basiert komplett auf einer 64-Bit-Architektur, genau wie alle anderen Programme, die mit dem Mac kommen. Das bedeutet: Alles, was Sie auf Ihrem MacBook Pro machen, passiert superschnell und mit einer unglaublichen Gesamtleistung.
 
Hat eine ganze Menge draufProgramme, ebenso leistungsstark wie benutzerfreundlich.
Weil Apple sowohl das MacBook Pro, wie auch die integrierte Software entwickelt, arbeitet alles perfekt zusammen. Und mit den Apple Programmen sind Sie ganz schnell vertraut, weil alle ähnlich funktionieren. Das heißt, wenn Sie ein Programm kennen, sind Sie auch schnell mit allen anderen vertraut. Außerdem weiß Apple genau, was mobile Produktivität bedeutet. Darum haben wir Funktionen wie Expose und Spaces hinzugefügt. Damit können Sie ganz einfach auf alles auf Ihrem MacBook Pro zugreifen. Expose zeigt sämtliche geöffneten Fenster nebeneinander, verkleinert sie und ordnet sie so, dass Sie den Inhalt jedes Fensters sehen können - ein Tastendruck oder eine Geste genügt. Und mit Spaces können Sie Fenster zusammen auf ihrem eigenen Schreibtisch oder Bereich gruppieren und ganz einfach zwischen diesen wechseln. Legen Sie einen Bereich zum Arbeiten fest, einen zum Spielen und einen für was auch immer. Mit Expose und Spaces haben Sie beim Multitasking auf einem Notebookdisplay einen riesigen Vorteil.
 
Darauf verzichten Sie beim Mac: PC-Viren.
Trojaner, Würmer, E-Mail Viren. Die digitale Welt kann ganz schön beängstigend sein. Zum Glück ist der Mac immun gegen die tausenden von Viren, die Windows Computer plagen. Denn Mac OS X kommt mit integrierten Sicherheitsmechanismen, die Sie schützen - ohne dass Sie etwas machen müssen. Und sollten doch mal potenzielle Sicherheitsrisiken auftreten, reagiert Apple sofort und stellt neue Softwareaktualisierungen und Sicherheitsverbesserungen bereit, die Sie automatisch laden und mit einem Klick installieren können.
 
Das automatische Backup rettet Ihren Tag. Und die Woche, den Monat ...
Backups müssen sein. Trotzdem vergissen Sie sie bestimmt hin und wieder. Deshalb kümmert sich jetzt das MacBook Pro um die Datensicherung. Time Machine, ein Programm, das auf jedem Mac dabei ist, sichert automatisch Ihr ganzes System auf einer externen Festplatte oder Time Capsule. Time Machine speichert eine Kopie von jeder Datei. Und es merkt sich, wie Ihr System an einem bestimmten Tag ausgesehen hat. So können Sie, wenn Sie wollen, die Zeit zurückdrehen und Ihren Mac wie in der Vergangenheit sehen.
 
Mit iMovie können Sie aus Ihren Videos großartige Filme machenAuch die täglichen Sachen machen mehr Spaß.
Anders als viele PC-Notebooks kommt das MacBook Pro mit allem, was Sie brauchen, um E-Mails zu senden, Kalender zu verwalten, Kontakte zu organisieren und mehr. Und Sie können schon wenige Minuten nach dem Auspacken damit loslegen. Denn jeder Mac kommt mit Mail, um E-Mails zu senden und empfangen, iCal zum Organisieren von Terminen und wichtigen Ereignissen, dem Adressbuch zum Verwalten von Kontakten, iTunes für alles, was mit Unterhaltung zu tun hat, und weiteren tollen und nützlichen Programmen, die Sie jeden Tag verwenden werden.
 
Der Mac App Store. Tausend weitere Gründe, den Mac zu lieben.
Über tausend Mac Apps sind nur einen Klick entfernt - im Mac App Store. Suchen Sie einfach Apps, die Ihnen gefallen, und klicken Sie einfach, um sie zu laden und zu installieren. Ohne Verpackung. Ohne CDs oder DVDs. Und ohne Probleme. Sie können die Apps nach Kategorien durchstöbern oder direkt etwas Bestimmtes suchen. Und Sie können einfach dafür sorgen, dass Ihre Apps up-to-date sind, denn Ihr Mac zeigt Ihnen an, wann Updates verfügbar sind.
 
iPhoto. Fotos ganz einfach verwalten, bearbeiten und teilen.
iPhoto ist ein benutzerfreundliches Programm für Fotos, mit dem Sie Ihre Bilder schnell organisieren, wiederfinden und verbessern können - sodass sie immer perfekt aussehen. Mit den iPhoto Funktionen ""Gesichter"", ""Orte"" und ""Ereignisse"" behalten Sie den Überblick über Ihre Fotos. Sie sagen Ihnen, wen Sie fotografiert haben, wo und wann. Und all das in den neuen Vollbildmodi.
 
iMovie. Und aus Homevideos werden Home-Blockbuster.
Homevideos müssen nicht langweilig sein. Mit iMovie können Sie aus Ihren Videos großartige Filme machen. Zum Beispiel Trailer im Hollywoodstil, mit denen Sie Ihr Publikum begeistern.
 
GarageBand. Großartige Musik machen, ganz einfachissimo.
Egal, ob Sie Musiktalent haben oder einfach nur neugierig sind - GarageBand ist genau das richtige Programm für Sie. Schließ einfach eine elektrische Gitarre oder ein USB Keyboard an. Und schon können Sie mit virtuellen Nachbildungen der bekanntesten Amps und Stompboxes der Welt sowie mit 100 Software-Instrumenten spielen.
";2;False;0;;;Apple MacBook Pro MC721D/A 15,4 Zoll Notebook;apple-macbook-pro-mc721da-154-zoll-notebook;True;True;P-0760;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;1483.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40652,8677546296;3;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000545-apple-macbook-pro-mc721da-154-zoll-notebook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000546-apple-macbook-pro-mc721da-154-zoll-notebook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000547-apple-macbook-pro-mc721da-154-zoll-notebook.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Apple MacBook Pro MD313D/A 13,3 Zoll Notebook;"Apple MacBook Pro MD313D/A 33,78cm (13,3"")";"
Apple MacBook Pro MD313D/A 13,3 Zoll Notebook
Intel Core i5  2x 2,40 GHz
 
Bis zu 2x schnellere Prozessoren. Bis zu 3x schnellere Grafik.
Quad-Core und Dual-Core Intel Prozessoren der nächsten Generation.
Das 13"" MacBook Pro gibt es jetzt mit einem 2,4 GHz Intel Core i5 Prozessor oder dem schnellsten Dual-Core Prozessor, den es gibt: dem 2,8 GHz Intel Core i7. Diese Prozessoren bieten Turbo Boost Geschwindigkeiten und machen das 13"" MacBook Pro bis zu doppelt so schnell wie die Vorgängergeneration.
 
Aber nur schnell ist uns nicht genug. Deshalb bieten die neuen 15"" und 17"" Modelle Quad-Core Leistung für praktisch alles, was du machen willst. Auch ein 2,4 GHz Quad-Core Intel Core i7 Prozessor mit Turbo Boost Geschwindigkeiten und bis zu 8 MB gemeinsam genutztem L3-Cache ist verfügbar. Auf MacBook Pro Modellen mit diesem Prozessor laufen Programme bis zu doppelt so schnell wie auf der besten Vorgängerkonfiguration.
 
Die Grafikleistung, die du brauchst, wenn du sie brauchst.
Alle MacBook Pro Modelle haben jetzt einen integrierten Intel HD Graphics 3000 Prozessor für die täglichen Aufgaben. Er codiert Videos schnell, ermöglicht HD Videotelefonate mit FaceTime und vieles mehr. Und auch Decodieren erledigt er effizienter, was bedeutet, dass du richtig lange DVDs und iTunes Filme schauen kannst.
 
Bei anspruchsvollen Grafikprogrammen wechseln die 15"" und 17"" MacBook Pro Modelle automatisch den Grafikprozessor und arbeiten mit den neuen leistungsstarken AMD Radeon Grafikprozessoren. Diese bieten verglichen mit den Vorgängermodellen die bis zu 3-fache Leistung.3 So siehst du bei 3D Spielen mehr Bilder pro Sekunde oder kannst schneller als je zuvor an HD Videoprojekten arbeiten.
 
Das neue Thunderbolt. Die schnellste, vielseitigste I/O Technologie in einem Notebook.
Stell dir vor, du könntest auf deinem Notebook auf mehrere unkomprimierte HD Videostreams zugreifen - und zwar so schnell, dass du einen HD Spielfilm in Echtzeit schneiden kannst. Thunderbolt macht genau das möglich. Mit Thunderbolt lassen sich superschnelle Peripheriegeräte der nächsten Generation an die Computer der nächsten Generation anschließen - angefangen beim MacBook Pro. Die Thunderbolt Pipeline ist ultraschnell und ultraflexibel. Sie ist über 12 Mal schneller als FireWire 800 und bis zu 20 Mal schneller als USB 2.0. Und sie bietet beispiellose Erweiterungsmöglichkeiten. Kurzum: Sie verändert alles, was du auf deinem Notebook machen kannst.
 
Der Thunderbolt Anschluss gibt dir Plug&Play Anschluss für eine völlig neue Welt von Thunderbolt Peripheriegeräten sowie für das Apple LED Cinema Display und andere Mini DisplayPort Peripheriegeräte. Du kannst bis zu sechs Thunderbolt Geräte in Reihenschaltung anschließen, darunter auch dein Display. Außerdem unterstützt Thunderbolt Video und Achtkanal-Audio, sodass es auch möglich ist, HDMI-kompatible Geräte wie Fernseher oder Stereoanlagen über einen HDMI-Adapter anzuschließen. Auch aktuelle VGA-, DVI- und DisplayPort Adapter werden unterstützt.
 
Die neue FaceTime HD Kamera. Der Unterschied ist ganz klar.
Sieh mehr von deinen Freunden mit dem HD Widescreenformat - und zwar gestochen scharf. Die neue FaceTime HD Kamera bietet die dreifache Auflösung der vorherigen Kamera, was perfekt für das brillante Display mit LED-Hintergrundbeleuchtung ist. Außerdem arbeitet sie jetzt bei schwachem Licht noch besser. Du kannst mit deinen Freunden HD Telefonate in 720p von einem neuen MacBook Pro zu einem anderen führen. Außerdem sind auch Videotelefonate zu anderen Macs mit Intel Prozessor5, zum iPhone 4 oder zum neuen iPod touch möglich.
 
Multi-Touch Trackpad. Fürs tägliche Handwerk.
Mit dem Multi-Touch Trackpad interagierst du auf ganz natürliche Art mit den Inhalten auf deinem Display. Und die glatte Glasoberfläche bietet jede Menge Platz für Gesten. Durch Auf- und Zuziehen kannst du ein- und auszoomen, durch Streichen in deinen Fotos blättern, durch Drehen ein Bild anpassen und vieles mehr. Das Trackpad kommt ohne Taste aus, sodass du überall klicken kannst. Wenn du aus der Welt des rechten Mausklicks kommst, kannst du diesen entweder mit zwei Fingern auslösen, oder du konfigurierst einen physischen Rechtsklick-Bereich auf dem Trackpad. Je mehr du mit dem Multi-Touch Trackpad vertraut bist, desto mehr wirst du dich fragen, wie du jemals ohne ausgekommen bist.
 
Lange Laufzeit. Weniger aufladen. Mehr machen.
Das neue MacBook Pro bietet eine fantastische Batterielaufzeit und das mit leistungsstärkeren Prozessoren und schnelleren Grafikprozessoren. Die energieeffiziente Prozessorarchitektur mit integriertem Video-Encoder sowie das automatische Umschalten zwischen den Grafikprozessoren bei den 15"" und 17"" Modellen helfen, die Batterielaufzeit weiter zu verbessern. So kannst du pro Ladung bis zu 7 Stunden ohne Kabel im Web surfen6 oder es für Liveauftritte oder auf ein Shooting mitnehmen. Die fortschrittlichen chemischen Eigenschaften und die Adaptive Charging Technologie sorgen dafür, dass die Batterie bis zu 1000 Ladezyklen durchlaufen kann.7 Und da die Batterie des MacBook Pro bis zu fünf Jahre hält, kommt das MacBook Pro in einem Zeitraum, in dem ein herkömmliches Notebook drei Batterien verbraucht, mit nur einer aus. Das ist für die Benutzer genauso gut, wie für die Umwelt.
 
Apple verwendet eine neue, strengere Testmethode, um zu messen, welche Ergebnisse du unter realen Bedingungen erzielst, z. B. beim Surfen in einem Café oder wenn du die neuesten Webvideos ansiehst. Und wie schneidet dieses MacBook Pro dabei verglichen mit der Vorgängergeneration ab? Es liefert die gleiche fantastische Leistung.
 
Hat beste Verbindungen.
Unterwegs hast du mit der 802.11n Technologie im MacBook Pro immer Verbindung.8 Das MacBook Pro findet automatisch verfügbare Netzwerke und du kannst dich mit einem Klick verbinden. Auch die drahtlose Bluetooth Technologie ist integriert, sodass du drahtloses Zubehör sofort nach dem Auspacken verwenden kannst.
 
Immer Anschluss finden.
Mit dem neuen Thunderbolt Anschluss kannst du bis zu sechs Geräte in Reihenschaltung anschließen, darunter auch dein Display. So bekommst du eine vollwertige Workstation. Für die Anbindung von iPad, iPod, iPhone, Digitalkameras und externen Festplatten gibt es zwei USB 2.0 Anschlüsse (drei beim 17"" MacBook Pro) und einen FireWire 800 Anschluss.
 
Der neue SDXC Kartensteckplatz der 13"" und 15"" MacBook Pro Modelle unterstützt bis zu 64 GB Karten und macht es leicht, alle deine Fotos auf und von deinem MacBook Pro zu übertragen, damit du sie sofort bearbeiten und teilen kannst. Und der ExpressCard/34 Steckplatz am 17"" MacBook Pro ist perfekt für einen eSATA Adapter geeignet oder sogar für eine 3G Karte für die drahtlose Kommunikation, wenn kein Wi-Fi Netzwerk vorhanden ist.
 
DVDs superschnell brennen.
Homevideos, die du mit iMovie und iDVD gemacht hast, kannst du mit dem 8-fach SuperDrive Laufwerk des MacBook Pro superschnell auf eine DVD brennen. Das SuperDrive kann auch Double-Layer-DVDs (also DVDs mit fast 9 GB Speicherplatz) beschreiben, sodass es auch hervorragend für Datensicherungen geeignet ist.
";2;False;0;;;Apple MacBook Pro MD313D/A 13,3 Zoll Notebook;apple-macbook-pro-md313da-133-zoll-notebook;True;True;P-0740;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;1099.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40652,639537037;3;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000456-apple-macbook-pro-md313da-133-zoll-notebook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000457-apple-macbook-pro-md313da-133-zoll-notebook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000458-apple-macbook-pro-md313da-133-zoll-notebook.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Apple MacBook Pro MC725D/A 17 Zoll Notebook;"Apple MacBook Pro MC725D/A 43.2 cm (17 Zoll) Notebook (Intel Core i7 2720QM, 2,2 GHz, 4GB RAM, 750GB HDD, AMD 6750M, DVD, Mac OS) ";"
Apple MacBook Pro MC725D/A
Intel Core i7 2720QM, 2,2 GHz
 
Stark, leicht und schön in einem.
Das MacBook Pro ist aus einem einzigen Aluminiumblock gefertigt - eine technische Meisterleistung, bei der viele Bauteile durch ein einziges ersetzt werden. Das Ganze nennt sich Unibody. Gleich beim ersten Mal, wenn Sie ein MacBook Pro in der Hand haben, werden Sie den Unterschied spüren. Das Gehäuse ist dünner und leichter als andere Notebooks. Es sieht elegant aus. Und es fühlt sich stabil und robust an: perfekt für die Aktentasche, den Rucksack und natürlich auch für draußen.
 
Ein Display voll brillanter Ideen.
Alles, was Apple Designer und Ingenieure tun, ist von A bis Z durchdacht. Sie entschieden sich beim MacBook Pro für die LED-Hintergrundbeleuchtung, weil das Display damit sofort seine volle Helligkeit erreicht und trotzdem unglaublich dünn ist. Sie verwendeten eine durchgehende Oberfläche aus Glas, nicht nur weil es schön aussieht, sondern weil es dem ganzen Display Struktur verleiht. Und über dem Bildschirm haben sie die neue, integrierte FaceTime HD Kamera versteckt. So siehst du Freunde und Familie im Großformat - und dabei so gut wie nichts von der Kamera.
 
Magnetverschluss
Da der magnetische Verschluss keine beweglichen Teile hat, die abbrechen können oder an denen man hängen bleibt, ist das Öffnen und Schließen so einfach wie alles beim MacBook Pro.
 
Einfach auf alle Anschlüsse zugreifen.
Alle Anschlüsse am MacBook Pro - der MagSafe Netzanschluss, der Gigabit Ethernetanschluss, der Thunderbolt Anschluss, der USB Anschluss, der Karten-Steckplatz und der Audioeingang und -ausgang - sind ganz auf einer Seite des Notebooks integriert. So bleiben die Kabel schön geordnet und Geräte lassen sich schnell und einfach anschließen und auch wieder trennen.
 
Hinterlässt Eindruck. Aber nicht auf die Umwelt.
Weil Apple die vollständige Kontrolle über Design, Fertigung und Verpackung des MacBook Pro hat, hat Apple einen Vorsprung beim Umweltschutz. Die Technologie zur Hintergrundbeleuchtung des Displays spart Energie. Glas und Aluminium sind besonders recyclingfähig. Das MacBook Pro kommt fast ohne Giftstoffe aus. Und die Verpackung des 43,18 cm / 17"" Modells ist im Vergleich zum Vorgängermodell 34 Prozent kleiner. Das bedeutet nicht nur, dass für die Verpackungen weniger Bäume gefällt werden, es werden für den Transport auch weniger Flugzeugen, Güterzügen und LKWs benötigt.
 
Thunderbolt AnschlussDie Grafikleistung, die Sie brauchen, wenn Sie sie brauchen.
Alle MacBook Pro Modelle haben jetzt einen integrierten Intel HD Graphics 3000 Prozessor für die täglichen Aufgaben. Er codiert Videos schnell, ermöglicht HD Videotelefonate mit FaceTime und vieles mehr. Und auch Decodieren erledigt er effizienter, was bedeutet, dass Sie richtig lange DVDs und iTunes Filme schauen können. Bei anspruchsvollen Grafikprogrammen wechseln die 43,18 cm / 17"" MacBook Pro Modelle automatisch den Grafikprozessor und arbeiten mit den neuen leistungsstarken AMD Radeon Grafikprozessoren. Diese bieten verglichen mit den Vorgängermodellen die bis zu 3-fache Leistung. So sehen Sie bei 3D Spielen mehr Bilder pro Sekunde oder können schneller als je zuvor an HD Videoprojekten arbeiten.
 
Das neue Thunderbolt. Die schnellste, vielseitigste I/O Technologie in einem Notebook.
Stellen Sie sich vor, Sie könnten auf deinem Notebook auf mehrere unkomprimierte HD Videostreams zugreifen - und zwar so schnell, dass Sie einen HD Spielfilm in Echtzeit schneiden können. Thunderbolt macht genau das möglich. Mit Thunderbolt lassen sich superschnelle Peripheriegeräte der nächsten Generation an die Computer der nächsten Generation anschließen - angefangen beim MacBook Pro. Die Thunderbolt Pipeline ist ultraschnell und ultraflexibel. Sie ist über 12 Mal schneller als FireWire 800 und bis zu 20 Mal schneller als USB 2.0. Und sie bietet beispiellose Erweiterungsmöglichkeiten. Kurzum: Sie verändert alles, was Sie auf Ihrem Notebook machen können. Der Thunderbolt Anschluss gibt Ihnen Plug&Play Anschluss für eine völlig neue Welt von Thunderbolt Peripheriegeräten sowie für das Apple LED Cinema Display und andere Mini DisplayPort Peripheriegeräte. Sie können bis zu sechs Thunderbolt Geräte in Reihenschaltung anschließen, darunter auch Ihr Display. Außerdem unterstützt Thunderbolt Video und Achtkanal-Audio, sodass es auch möglich ist, HDMI-kompatible Geräte wie Fernseher oder Stereoanlagen über einen HDMI-Adapter anzuschließen. Auch aktuelle VGA-, DVI- und DisplayPort Adapter werden unterstützt.
 
Die neue FaceTime HD Kamera. Der Unterschied ist ganz klar.
Sehen Sie mehr von Ihren Freunden mit dem HD Widescreenformat - und zwar gestochen scharf. Die neue FaceTime HD Kamera bietet die dreifache Auflösung der vorherigen Kamera, was perfekt für das brillante Display mit LED-Hintergrundbeleuchtung ist. Außerdem arbeitet sie jetzt bei schwachem Licht noch besser. Sie können mit Ihren Freunden HD Telefonate in 720p von einem neuen MacBook Pro zu einem anderen führen. Außerdem sind auch Videotelefonate zu anderen Macs mit Intel Prozessor, zum iPhone 4 oder zum neuen iPod touch möglich.
 
Multi-Touch Trackpad - Jede Menge Platz für GestenMulti-Touch Trackpad. Fürs tägliche Handwerk.
Mit dem Multi-Touch Trackpad interagieren Sie auf ganz natürliche Art mit den Inhalten auf deinem Display. Und die glatte Glasoberfläche bietet jede Menge Platz für Gesten. Durch Auf- und Zuziehen können Sie ein- und auszoomen, durch Streichen in deinen Fotos blättern, durch Drehen ein Bild anpassen und vieles mehr. Das Trackpad kommt ohne Taste aus, sodass Sie überall klicken können. Wenn Sie aus der Welt des rechten Mausklicks kommen, können Sie diesen entweder mit zwei Fingern auslösen, oder Sie konfigurieren einen physischen Rechtsklick-Bereich auf dem Trackpad. Je mehr Sie mit dem Multi-Touch Trackpad vertraut sind, desto mehr werden Sie sich fragen, wie Sie jemals ohne ausgekommen sind.
 
Lange Laufzeit. Weniger aufladen. Mehr machen.
Das neue MacBook Pro bietet eine fantastische Batterielaufzeit und das mit leistungsstärkeren Prozessoren und schnelleren Grafikprozessoren. Die energieeffiziente Prozessorarchitektur mit integriertem Video-Encoder sowie das automatische Umschalten zwischen den Grafikprozessoren bei den 43,18 cm / 17"" Modellen helfen, die Batterielaufzeit weiter zu verbessern. So können Sie pro Ladung bis zu 7 Stunden ohne Kabel im Web surfen oder es für Liveauftritte oder auf ein Shooting mitnehmen. Die fortschrittlichen chemischen Eigenschaften und die Adaptive Charging Technologie sorgen dafür, dass die Batterie bis zu 1000 Ladezyklen durchlaufen kann. Und da die Batterie des MacBook Pro bis zu fünf Jahre hält, kommt das MacBook Pro in einem Zeitraum, in dem ein herkömmliches Notebook drei Batterien verbraucht, mit nur einer aus. Das ist für die Benutzer genauso gut, wie für die Umwelt. Apple verwendet eine neue, strengere Testmethode, um zu messen, welche Ergebnisse Sie unter realen Bedingungen erzielen, z. B. beim Surfen in einem Cafe oder wenn Sie die neuesten Webvideos ansehen. Und wie schneidet dieses MacBook Pro dabei verglichen mit der Vorgängergeneration ab? Es liefert die gleiche fantastische Leistung.
 
Hat beste Verbindungen.
Unterwegs haben Sie mit der 802.11n Technologie im MacBook Pro immer Verbindung. Das MacBook Pro findet automatisch verfügbare Netzwerke und Sie können sich mit einem Klick verbinden. Auch die drahtlose Bluetooth Technologie ist integriert, sodass Sie drahtloses Zubehör sofort nach dem Auspacken verwenden können.
 
DVDs superschnell brennen.
Homevideos, die Sie mit iMovie und iDVD gemacht haben, können Sie mit dem 8-fach SuperDrive Laufwerk des MacBook Pro superschnell auf eine DVD brennen. Das SuperDrive kann auch Double-Layer-DVDs (also DVDs mit fast 9 GB Speicherplatz) beschreiben, sodass es auch hervorragend für Datensicherungen geeignet ist.
 
Neue Intel Core i7 Prozessoren.
Neue Quad-Core Intel Core i7 Prozessoren sind Standard beim 43,18 cm / 17"" MacBook Pro. Alle Modelle verwenden die kürzlich optimierten Chipsets von Intel. Was heißt das für die neuen MacBook Pro Modelle? Kurz gesagt: Sie sind bis zu zwei Mal schneller als die Vorgängergeneration und erledigen auch anspruchsvolle Aufgaben wie HD Videoschnitt, Audiokompilierung oder Rendering mehrschichtiger Bilddateien unglaublich schnell. Und da Mac OS X Snow Leopard darauf ausgelegt ist, jeden Prozessorkern zu nutzen, holt das Betriebssystem wirklich alles an Leistung aus dem Prozessor heraus.
 
Schnellere Einzelchip-Mikroarchitektur.
Ob Sie einen Film ansehen, Ihren Blog auf den neuesten Stand bringen oder Fotos bearbeiten - die Daten müssen von A nach B gelangen, um verarbeitet werden zu können. Die neueste Intel Core Architektur bringt den Prozessor, den Cache, den Speichercontroller und den Grafikprozessor auf einem einzigen Chip unter. Deswegen müssen die Daten keine weiten Wege zurücklegen, was für Sie schnellere Performance und höhere Effizienz bedeutet.
 
Turbo Boost 2.0.
Angenommen, Sie arbeiten mit einem prozessorintensiven Programm wie Aperture 3 oder Final Cut Pro, das von einem Leistungsschub profitiert würde. Turbo Boost ist eine dynamische Technologie, die automatisch die Geschwindigkeit der aktiven Prozessorkerne auf 3,4 GHz erhöht. Turbo Boost 2.0 ist noch dynamischer und effizienter. Es wechselt die Kernfrequenz in kleineren Schritten als bisher, sodass der Prozessor die Leistung ohne Effizienzeinbußen verwalten kann. All das passiert im Hintergrund. Sie arbeiten einfach nur schneller.
 
Hyper-Threading.
Hyper-Threading ist jetzt Standard auf jedem MacBook Pro. Mit dieser Technologie können auf jedem Kern zwei Threads gleichzeitig laufen, Mac OS X erkennt also bei einem Quad-Core Prozessor acht und bei einem Dual-Core Prozessor vier virtuelle Kerne. Wenn Sie mehrere Programme gleichzeitig verwenden, verteilt der Prozessor die Aufgaben gleichmäßiger über eine größere Anzahl Kerne.
 
Integrierter Speichercontroller.
Mit schnellerem Speicherzugriff legt jeder Kern direkt mit der Verarbeitung der Daten los, statt auf ihr Eintreffen zu warten. Genau deshalb nutzt die neue Intel Core Architektur einen integrierten Speichercontroller, der den schnellen 1333 MHz Speicher direkt mit dem Prozessor verbindet und Ihre Programme immer die maximale Prozessorleistung zur Verfügung haben.
 
Energieeffiziente Grafik.
Dank der neuen Mikroarchitektur ist der Grafikprozessor auf dem gleichen Chip wie der Zentralprozessor und hat direkten Zugriff auf den L3-Cache. Kurze Wege bedeuten mehr Leistung. Der Grafikprozessor erhöht auch automatisch die Taktrate für noch höhere Auslastung. Ein integrierter Video-Encoder ermöglicht jetzt HD Videotelefonate mit FaceTime, und der effiziente Decoder sorgt für lange Batterielaufzeit, wenn Sie sich DVDs oder iTunes Filme ansiehen.
 
Mac OS X. Das fortschrittlichste Betriebssystem der Welt.
Mac OS X ist das Herz jedes MacBook Pro und Mac. Dieses Betriebssystem ist genau auf die integrierten Intel Multicore-Prozessoren und fortschrittlichen Grafikprozessoren zugeschnitten. Die neueste Version, Mac OS X Snow Leopard, basiert komplett auf einer 64-Bit-Architektur, genau wie alle anderen Programme, die mit dem Mac kommen. Das bedeutet: Alles, was Sie auf Ihrem MacBook Pro machen, passiert superschnell und mit einer unglaublichen Gesamtleistung.
 
Hat eine ganze Menge draufProgramme, ebenso leistungsstark wie benutzerfreundlich.
Weil Apple sowohl das MacBook Pro, wie auch die integrierte Software entwickelt, arbeitet alles perfekt zusammen. Und mit den Apple Programmen sind Sie ganz schnell vertraut, weil alle ähnlich funktionieren. Das heißt, wenn Sie ein Programm kennen, sind Sie auch schnell mit allen anderen vertraut. Außerdem weiß Apple genau, was mobile Produktivität bedeutet. Darum haben wir Funktionen wie Expose und Spaces hinzugefügt. Damit können Sie ganz einfach auf alles auf Ihrem MacBook Pro zugreifen. Expose zeigt sämtliche geöffneten Fenster nebeneinander, verkleinert sie und ordnet sie so, dass Sie den Inhalt jedes Fensters sehen können - ein Tastendruck oder eine Geste genügt. Und mit Spaces können Sie Fenster zusammen auf ihrem eigenen Schreibtisch oder Bereich gruppieren und ganz einfach zwischen diesen wechseln. Legen Sie einen Bereich zum Arbeiten fest, einen zum Spielen und einen für was auch immer. Mit Expose und Spaces haben Sie beim Multitasking auf einem Notebookdisplay einen riesigen Vorteil.
 
Darauf verzichten Sie beim Mac: PC-Viren.
Trojaner, Würmer, E-Mail Viren. Die digitale Welt kann ganz schön beängstigend sein. Zum Glück ist der Mac immun gegen die tausenden von Viren, die Windows Computer plagen. Denn Mac OS X kommt mit integrierten Sicherheitsmechanismen, die Sie schützen - ohne dass Sie etwas machen müssen. Und sollten doch mal potenzielle Sicherheitsrisiken auftreten, reagiert Apple sofort und stellt neue Softwareaktualisierungen und Sicherheitsverbesserungen bereit, die Sie automatisch laden und mit einem Klick installieren können.
 
Das automatische Backup rettet Ihren Tag. Und die Woche, den Monat ...
Backups müssen sein. Trotzdem vergissen Sie sie bestimmt hin und wieder. Deshalb kümmert sich jetzt das MacBook Pro um die Datensicherung. Time Machine, ein Programm, das auf jedem Mac dabei ist, sichert automatisch Ihr ganzes System auf einer externen Festplatte oder Time Capsule. Time Machine speichert eine Kopie von jeder Datei. Und es merkt sich, wie Ihr System an einem bestimmten Tag ausgesehen hat. So können Sie, wenn Sie wollen, die Zeit zurückdrehen und Ihren Mac wie in der Vergangenheit sehen.
 
Mit iMovie können Sie aus Ihren Videos großartige Filme machenAuch die täglichen Sachen machen mehr Spaß.
Anders als viele PC-Notebooks kommt das MacBook Pro mit allem, was Sie brauchen, um E-Mails zu senden, Kalender zu verwalten, Kontakte zu organisieren und mehr. Und Sie können schon wenige Minuten nach dem Auspacken damit loslegen. Denn jeder Mac kommt mit Mail, um E-Mails zu senden und empfangen, iCal zum Organisieren von Terminen und wichtigen Ereignissen, dem Adressbuch zum Verwalten von Kontakten, iTunes für alles, was mit Unterhaltung zu tun hat, und weiteren tollen und nützlichen Programmen, die Sie jeden Tag verwenden werden.
 
Der Mac App Store. Tausend weitere Gründe, den Mac zu lieben.
Über tausend Mac Apps sind nur einen Klick entfernt - im Mac App Store. Suchen Sie einfach Apps, die Ihnen gefallen, und klicken Sie einfach, um sie zu laden und zu installieren. Ohne Verpackung. Ohne CDs oder DVDs. Und ohne Probleme. Sie können die Apps nach Kategorien durchstöbern oder direkt etwas Bestimmtes suchen. Und Sie können einfach dafür sorgen, dass Ihre Apps up-to-date sind, denn Ihr Mac zeigt Ihnen an, wann Updates verfügbar sind.
 
iPhoto. Fotos ganz einfach verwalten, bearbeiten und teilen.
iPhoto ist ein benutzerfreundliches Programm für Fotos, mit dem Sie Ihre Bilder schnell organisieren, wiederfinden und verbessern können - sodass sie immer perfekt aussehen. Mit den iPhoto Funktionen ""Gesichter"", ""Orte"" und ""Ereignisse"" behalten Sie den Überblick über Ihre Fotos. Sie sagen Ihnen, wen Sie fotografiert haben, wo und wann. Und all das in den neuen Vollbildmodi.
 
iMovie. Und aus Homevideos werden Home-Blockbuster.
Homevideos müssen nicht langweilig sein. Mit iMovie können Sie aus Ihren Videos großartige Filme machen. Zum Beispiel Trailer im Hollywoodstil, mit denen Sie Ihr Publikum begeistern.
 
GarageBand. Großartige Musik machen, ganz einfachissimo.
Egal, ob Sie Musiktalent haben oder einfach nur neugierig sind - GarageBand ist genau das richtige Programm für Sie. Schließ einfach eine elektrische Gitarre oder ein USB Keyboard an. Und schon können Sie mit virtuellen Nachbildungen der bekanntesten Amps und Stompboxes der Welt sowie mit 100 Software-Instrumenten spielen.  
";2;False;0;;;Apple MacBook Pro MC725D/A 17 Zoll Notebook;apple-macbook-pro-mc725da-17-zoll-notebook;True;True;P-0700;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;2299.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40652,5987037037;3;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000312-apple-macbook-pro-mc725da-17-zoll-notebook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000313-apple-macbook-pro-mc725da-17-zoll-notebook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000314-apple-macbook-pro-mc725da-17-zoll-notebook.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Apple iPod Nano 8 GB 6. Gen. verschiedene Farben;Apple iPod Nano 8 GB 6. Generation verschiedene Farben;"
Der Remix für Ihre Finger
Der iPod nano mit Multi-Touch ist einfach, intuitiv und macht jede Menge Spaß - wie Ihre Musik. Und er ist jetzt noch kleiner, damit Musik bei allem, was Sie machen, eine größere Rolle spielen kann.
 
Musik. Fühlen Sie den Beat
Ihre Greatest Hits. Zum Anfassen
Die besten Dinge im Leben kommen mit Soundtrack. Und genau da glänzt der iPod nano. Mit dem Multi-Touch Display können Sie Ihre Musik ganz neu erleben. Ein Tipp genügt und er spielt, was Sie hören wollen. Stöbern Sie in Ihrer Musik nach Songs, Alben, Interpreten, Wiedergabelisten, Genres oder Komponisten - streichen Sie dazu über den Homescreen. Sie können sogar die Symbole auf dem Homescreen neu ordnen, damit alles so ist, wie Sie es wollen.
 
Das ist ein echter Musikclip
Mit dem neuen integrierten Clip können Sie mit Ihren Lieblingssongs am Ärmel (oder in der Tasche, Jacke oder Hose) wandern, laufen, Rad fahren und abrocken. Und das Cover zum Song, der gerade läuft, passt perfekt auf das Display.
 
Rock around the clock
Die integrierte aufladbare Lithium-Ionen-Batterie sorgt für 24 Stunden Musik nonstop. Wenn Sie sich den 8 GB oder 16 GB iPod nano anklippen, haben Sie genug Songs für den Weg zur Arbeit, fürs Training und mehr.
 
Songs aus dem Finger schütteln
Überlassen Sie alles dem Zufall. Einfach den iPod nano kurz schütteln und er springt zu einem anderen Song aus Ihrer Sammlung. Schütteln ist perfekt, wenn Ihnen gerade nicht nach einer bestimmten Musik ist. Lassen Sie sich einfach überraschen.
 
Genius. Ihr Mixmaster
 
Eingebauter Clip

 
Ihr persönlicher DJ
Angenommen, Sie hören einen Song, der Ihnen gut gefällt, und möchten ähnliche hören. Ein Tipp auf Genius genügt. Genius findet weitere Songs auf Ihrem iPod nano, die gut dazu passen und erstellt eine Genius Wiedergabeliste für Sie. Wenn Sie einen Mix wollen, auf den Sie selbst nie gekommen wären, erstellen Sie einen Genius Mix in iTunes und synchronisieren ihn mit Ihrem iPod nano. Tippen Sie auf das Symbol für Genius Mixe und entdecken Sie Songs, die Sie lange nicht mehr gehört haben, oder Musik, von der Sie gar nicht mehr wussten, dass Sie sie haben.
 
FM Radio. Und Sie haben alles auf dem Sender
Radio nano
Mit dem iPod nano können Sie auf der Radiowelle surfen. Der FM Tuner zeigt Ihnen den Interpreten, Song oder Sender, der gerade läuft. Ein Tipp genügt und Sie sehen die Radiosteuerungen. Streichen Sie über den Tuner, um den Sender zu wechseln, und stellen Sie dann Ihre Lieblingssender per Fingertipp ein.
 
Live-Pause
Wenn Sie Ihre Lieblingssendung im Radio einmal kurz unterbrechen müssen, verpassen Sie dank Live-Pause trotzdem keinen einzigen Beat. Einfach Tippen und Sendung oder Song werden angehalten. Noch mal Tippen und es geht da weiter, wo Sie aufgehört haben. Sie können sogar bis zu 15 Minuten zurückspulen und dann vorspulen, um wieder live dabei zu sein.
 
Fitness. Treffen Sie Ihren neuen Trainer
 
Anklippen und los geht´s
Das neue Design des iPod nano hilft Ihnen fit zu bleiben. Weil er so klein und tragbar ist, ist er auch beim Joggen, Wandern und im Fitnessstudio immer dabei. Klippen Sie ihn an und steuern Sie Ihre Musik mit nur einem Tippen oder Streichen, sodass Sie sich voll auf Ihr Workout konzentrieren können. Ob Laufen, Walken oder der Weg zum Fitnessstudio - für den kleinen iPod nano ist kein Weg zu weit.
 
Schritte zum Fitbleiben
Sie können den iPod nano auch als Schrittzähler verwenden. Er zählt Ihre Schritte und hilft Ihnen beim Erreichen Ihrer Fitnessziele. Einfach anklippen und los geht´s. Sie können eine tägliche Schrittvorgabe festlegen und Ihre Fortschritte sehen, wenn Sie Ihre Daten auf die Nike+ Website laden.
 
Rocken Sie Ihr Training
Ob beim Joggen oder im Fitnessstudio, mit dem Nike + iPod Sport Kit (separat erhältlich) motiviert Sie der iPod nano vom Warm Up bis zum Cool Down. Ziehen Sie Ihre Nike+ Joggingschuhe an und klippen Sie sich den iPod nano an. Sehen Sie wie Sie Kilometer für Kilometer zurücklegen und hören Sie das Sprachfeedback in Echtzeit, während Ihre Songs laufen. Schließen Sie den iPod nano im Fitnessstudio an ein Gerät an, das mit Nike + iPod kompatibel ist. So zeichnet er Ihre Geschwindigkeit, die Dauer und die Laufstrecke auf, während Sie Ihr Training rocken.
 
iTunes. Damit der iPod was zu spielen hat
Alles für gute Unterhaltung
iTunes ist der beste Weg, Ihren iPod nano mit den neuesten Hits, Podcasts, Hörbüchern und vielem mehr zu füllen. Und auch die beste Art, Ihre immer weiter wachsende Sammlung digitaler Medien zu durchstöbern und auf dem Mac oder PC zu organisieren. Alle im iTunes Store gekauften Inhalte und alle von CDs importierten Songs werden in Ihrer Mediathek in iTunes angezeigt. Sie können Ihre eigenen oder Genius Wiedergabelisten erstellen, Genius Mixe auswählen und alles mit Ihrem iPod nano synchronisieren. Und iTunes ist als kostenloser Download verfügbar.
 
Der beste Music Store der Welt
Laden Sie Ihre Lieblingssongs auf Ihren iPod nano. Oder stöbern Sie in über 13 Millionen Songs und finden Sie weitere Hits. Sie können nach dem Namen eines Interpreten, Songs oder Albums suchen und so genau die richtigen Songs finden. Sie suchen neue Musik und brauchen Hilfe? Die Genius Seitenleiste empfiehlt Ihnen neue Musik, die auf Ihren Lieblingssongs basiert. Sie können in jeden Song kostenlos 30 Sekunden reinhören. Und mit einem Klick können Sie einen Song kaufen. Er wird dann sofort geladen. Schneller und einfacher können Sie Ihre digitale Musiksammlung für den iPod nicht zusammenstellen.
 
Bedienungshilfen
Integrierte Bedienungshilfen.
iPod nano kommt mit Bedienungshilfen, die Menschen mit Handicaps helfen Musik, Hörbücher und mehr zu erleben.
 
VoiceOver
Der iPod touch bietet VoiceOver, die weltweit erste Bildschirmlesefunktion, die auf Gesten basiert. Tippen Sie auf das Display und Sie hören eine Beschreibung des Objekts, das Sie gerade berühren. Steuern Sie den iPod nano durch Doppeltippen, Bewegen oder Streichen. Mit den optionalen Apple Earphones mit Fernbedienung und Mikrofon können Sie Ihre Musik steuern, ohne auf das Display zu sehen. VoiceOver nennt Ihnen den Song und Interpreten und spricht auch noch 29 Sprachen.
 
Weiß auf Schwarz
Wenn Sie stärkeren Kontrast möchten, stellen Sie das Display des iPod nano so ein, dass Weiß auf Schwarz angezeigt wird. Sie können diese Funktion in jeder App und auch auf dem Homescreen verwenden.
 
Mono Audio
Wenn Sie nur auf einem Ohr gut hören können, können Sie ""Mono-Audio"" aktivieren, damit die Audioausgabe auf beide Ohrhörer geleitet wird und Sie beide Kanäle mit dem gesunden Ohr hören können.

Produktbeschreibungen
 
Highlights
- Multi-Touch Display
- Genius - dein Mixmaster
- FM Radio
- iTunes
- Integrierte Bedienungshilfen (VoiceOver und Weiß auf Schwarz)
 
Akku
- Akkutyp: Li-Ion
- Akkulaufzeit bis zu 24 Stunden
 
Display
- Farbdisplay
- Bilddiagonale: 3,91 cm
- 1,54- Display
- Auflösung Breite: 240 Pixel
- Auflösung Höhe: 240 Pixel
 
Speicher
- Interner Speicher 8.000 MB
 
Stromversorgung
- USB-Lader
 
Wiedergabeformate Audio
- AAC
- MP3
- WAV
 
Grundeigenschaften
- Breite: 40,9 mm
- Höhe: 37,5 mm
- Tiefe: 8,78 mm
- Gewicht: 21,1 g
- Gewicht: 21,1 g
- Farbe: Dunkelgrau
 
Lieferumfang
- iPod nano
- Apple Earphones
-Dock Connector auf USB Kabel
- Dokumentation und wichtige Produktinformationen
";2;False;0;;;Apple iPod Nano 8 GB 6. Gen. verschiedene Farben;apple-ipod-nano-8-gb-6-gen-verschiedene-farben;True;True;PD-01073;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;149.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40652,5607638889;49;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000266-apple-ipod-nano-16-gb-6-gen-verschiedene-farben.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000267-apple-ipod-nano-16-gb-6-gen-verschiedene-farben.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000268-apple-ipod-nano-16-gb-6-gen-verschiedene-farben.jpg;3;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Apple MacBook Air MC966D/A-i7 13,3 Zoll Notebook;"Apple MacBook Air 33,78cm (13,3"") 1,8GHz i7 4GB 256GB SSD";"
Eindrücke:
Bei der Entwicklung des neuen MacBook Air gab’s nur ein Ziel: ein unglaublich dünnes und leichtes Notebook, genauso leistungsstark und vielseitig wie doppelt so große Geräte. Und mit Flash-Speicher,
 
stabilem Unibody-Gehäuse, Multi-Touch und einer ausdauernden
 
Batterie erreicht das MacBook Air nicht nur das Ziel, es ist der neue Standard, wie ein Notebook sein sollte. Perfekt bis ins letzte Detail.
 
Design:
Gerade mal 1,7 cm flach. Aber damit legt das neue MacBook Air die Messlatte sehr hoch - und es macht den Flash-Speicher zum Maßstab. Da Flash-Chips so klein sind, ist das MacBook Air so unglaublich dünn und leicht. Diese Flash-Chips sind Solid-State-Komponenten, sie arbeiten ohne bewegliche Teile. Das macht sie zuverlässig, robust und sehr leise beim Arbeiten. Und da wir sie direkt auf der Hauptplatine platzieren, brauchen sie viel weniger Platz – etwa 90 % weniger, um genau zu sein. Es bleibt mehr Platz für andere wichtige Dinge. Zum Beispiel eine größere Batterie. Damit ist ein Notebook entstanden, das fast nichts wiegt und mit einer Batterieladung stundenlang durchhält. So entsteht echte Mobilität.
 
Umweltverträglichkeit:
Die folgenden Merkmale des MacBook Air tragen zu seiner geringeren Umweltbelastung bei:
 
Frei von bromhaltigen Flammschutzmitteln
Ohne PVC
PVC-freie Netzkabel sind in Australien, Japan, Neuseeland, Nord- und Südamerika, der Schweiz, Taiwan, Thailand und Großbritannien verfügbar.
Hochgradig recyclebares Aluminiumgehäuse
ENERGY STAR 5.2 konform
EPEAT-Bewertung ""Gold""
Das MacBook Air hat in den USA und Kanada von der EPEAT die Bewertung ""Gold"" erhalten.
 
Mitgelieferte Software:
 
OS X Lion
Enthält Mail, Adressbuch, iCal, Mac App Store, iTunes, Safari, Time Machine, FaceTime, Photo Booth, Mission Control, Launchpad, AirDrop, Resume-Funktion, automatisches Sichern, Versionen, Übersicht, Spotlight, QuickTime und mehr.
 
iLife '11
Enthält iPhoto, iMovie und GarageBand.
 
Display:
 
Hochauflösendes 13,3"" Hochglanz-Widescreendisplay mit LED-Hintergrundbeleuchtung (33,78 cm Diagonale), Unterstützung für Millionen Farben
 
Unterstützte Auflösungen:
 
1440 x 900 (nativ), 1280 x 800, 1152 x 720 und 1024 x 640 Pixel bei einem Seitenverhältnis von 16:10, 1024 x 768 und 800 x 600 Pixel bei einem Seitenverhältnis von 4:3
";2;False;0;;;Apple MacBook Air MC966D/A-i7 13,3 Zoll Notebook;apple-macbook-air-mc966da-i7-133-zoll-notebook;True;True;P-0720;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;1599.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40652,0359953704;4;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000465-apple-macbook-air-mc966da-i7-133-zoll-notebook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000466-apple-macbook-air-mc966da-i7-133-zoll-notebook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000467-apple-macbook-air-mc966da-i7-133-zoll-notebook.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Samsung Galaxy S II (i9100) DualCore Smartphone weiß;Samsung Galaxy S II (i9100) DualCore Smartphone (10.9 cm (4.3 Zoll) Super-Amoled Plus Display, Android 2.3, 8 MP Full-HD Kamera, 2 MP Frontkamera) weiß;"
Samsung launcht mit dem Galaxy S II den Nachfolger des Bestsellers Galaxy S. Das Galaxy S II ist nicht nur das schlankste (8,49 mm), sondern dank des 1,2 GHz Dual-Core Prozessors auch das schnellste Smartphone seiner Klasse. Darüber hinaus besticht es durch ein 4,3"" Super Amoled Plus Touch-Display. Das Galaxy S II verwendet als Betriebssystem die aktuellste Android 2.3 Version – auch bekannt unter dem Namen Gingerbread. Die integrierte 8 Megapixel Kamera mit LED Blitz hält die schönsten Momente in erstklassiger Qualität fest – darüber hinaus ermöglicht die 2 Megapixel Frontkamera Video Telefonate in beeindruckender Qualität. Das Schreiben von E-Mails und SMS gelingt unkompliziert dank Swype®-Texteingabe. Zahlreiche aktuelle und nützliche Apps stehen im Android Market™ zum Download bereit. Die integrierte Google Maps Navigation™ führt ans gewünschte Ziel. AllShare, HD Video, Exchange ActiveSync und eine Vielzahl an weiteren Applikationen lassen keine Wünsche offen. Ein erstklassiges Zusammenspiel von Hardware und Funktionen leistet sein Übriges für ein ausgezeichnetes Nutzererlebnis auf höchstem Niveau!
 
4,27-Zoll SUPER AMOLED Plus
Bekennen Sie Farbe! Dieses brillante Display bietet den besten Farbumfang, ein hohes Kontrastverhältnis sowie ultimative Schärfe bei Bildern. Die bahnbrechende Verkürzung der Video-Reaktionszeit sorgt für ruckfreie Videowiedergabe. Die neue Technologie benötigt weniger Platz und Energie: Im Vergleich zum Vorgänger benötigt das Display 18% weniger Energie. Es ist damit eines der dünnsten, langlebigsten Smartphones am Markt.
 
Brillante Performance
Das Unmögliche ist möglich. Der Samsung Dual Core Application Prozessor ist die reaktionsschnelle Antwort im Bereich mobile Performance. Er bietet Multitasking in Hochgeschwindigkeit, schnelles Laden von Internetseiten, schnelle Reaktionszeiten, eine intuitive Benutzeroberfläche, blitzschnelle Bildbearbeitung und Spiele mit hoher Performance. Und mit der superschnellen Möglichkeit zum Encodieren und Decodieren, die alles im Bereich Videoaufzeichnung und -wiedergabe (1080p / 30fps) unterstützt, stellt er alle anderen Dual Core-Prozessoren in den Schatten. Problemloses Video- oder Musik-Streaming bekommt dank des schnellen Drahtlosstandards HSPA 21 Mbps einen großen Schub. Hervorragende Rechenleistung, herausstechende Performance.
 
Schlankes Design
Schlank, schlanker, GALAXY S II. Das Samsung GALAXY S II führt die Riege an – mit nur 8,49 mm und einem luxuriösen Design liegt es zudem gut in der Hand. Das GALAXY S II ist eines der schlanksten Smartphones und bietet außerdem HyperSkin für einen schönen Metall-Look mit einer fingerabdruckfreien und rutschfesten Akkuabdeckung.
 
Readers Hub
Lassen Sie Ihre Bücher zu Hause: Das Samsung GALAXY S II übernimmt diese Aufgabe. Stöbern Sie im Readers Hub in Ihrer Bücherei mit Klassikern oder suchen Sie in mehr als 2 Millionen Büchern die neusten Bestseller. Sie können auch 2.500 Magazine in 20 Sprachen und 1.600 Zeitungen in 47 Sprachen zur Lieferung einrichten. Mit klarem, deutlichem Text und der hohen Bedienerfreundlichkeit macht das Lesen Spaß: vergrößern, nur Text und Seitenansichten, Audiozugriff sowie schnelles Verteilen per E-Mail sind nur einige Funktionen. Glauben Sie an Bücher, beschränken Sie sich jedoch nicht nur auf Papier.
 
8-Megapixel-Kamera mit LED-Blitz
Immer gute Fotos. Der 8-Megapixel-Kamera mit Autofokus entgehen auch bei Action-Fotos keine Details. Machen Sie auch bei schlechten Lichtverhältnissen mit dem integrierten LED-Blitz wunderschöne und detaillierte Aufnahmen. Und dank der stark verbesserten Benutzeroberfläche von Android Gingerbread ist selbst schneller Szenenwechsel möglich. Wechseln Sie problemlos auf die 2-Megapixel-Kamera vorne, um Selbstporträts zu machen. Einfach immer gute Bilder.
 
Aufzeichnung & Wiedergabe in Full-HD
Werden Sie zum Star. Mit den Möglichkeiten zur Videoaufzeichnung des Samsung GALAXY S II können auch Sie zur Berühmtheit werden. Mit der 1080p Full-HD-Aufzeichnung ist jeder Moment ein potenzielles Meisterwerk in der Entstehung. Erfassen Sie die Action in hoher Auflösung und mit Dual Core-Geschwindigkeit und geben Sie Ihre HD-Aufzeichnungen mit bestechender Klarheit auf dem 4,3"" SUPER AMOLED Plus Display wieder.
 
Spracherkennung & Sprachübersetzung
Einfach Sprachbefehle nutzen. Tippen Sie nur doppelt auf die Home-Taste und steuern Sie das Samsung GALAXY S II mit ausgewählten Sprachbefehlen. Führen Sie wichtige Funktionen wie anrufen, Musik hören oder SMS schreiben mit einfachen Sprachbefehlen aus. Sie können auch Ihre Gedanken festhalten, sich selbst eine Notiz schreiben oder unterwegs sogar mit Google Voice Translation eine Übersetzung anfertigen. Galaxy S II kann Ihnen eingehende Nachrichten auch vorlesen.
 
Game Hub
Noch mehr Spielspaß. Über den Game Hub von Samsung GALAXY S II können Sie hochwertige Spiele herunterladen: 12 soziale Netzwerkspiele und 13 Prämiumspiele einschließlich Gameloft’s Let Golf 2 und Real Football 2011. Sie können nach Spielen und Informationen zu Neuerscheinungen suchen oder einfach nur spielen. Mit einem Beschleunigungsaufnehmer, einem magnetischen Sensor und Gyroskop-Sensor heben sich Spiele mit Hand- und Armbewegungen deutlich aus der Masse ab. Die kleinste Bewegung reicht bereits aus – das ist spannende Unterhaltung.
 
Social Hub
Mit dem Social Hub lassen sich Ihre Online-Kontakte besser organisieren und synchronisieren. Sammeln Sie Ihre Informationen aus E-Mails, SMS, IM und SNS in einem einheitlichen Posteingang – Interaktionen mit anderen sind so schneller und auf die von Ihnen gewünschte Art möglich.
 
Music Hub
Musik darf nicht fehlen. Der neue native Music-Player von Samsung bietet ein intuitives Wiedergabesystem zum Suchen, Entdecken, Anspielen, Kaufen und Herunterladen von Musikstücken für unterwegs. Die App bietet auch viele Informationen zum Kauf sowie Zugriff auf alle gewünschten Künstler, Liedtexte und Bewertungen. Sie können Empfehlungen für neue Songs abrufen und durch Bassverstärkung und 5.1 Kanal-Sound den Hörspaß noch mehr steigern.
 
Microsoft Exchange ActiveSync
Das Samsung GALAXY S II ist für sicheren Zugriff auf Unternehmensressourcen auf einem Microsoft Exchange Server optimiert, damit Sie in Bezug auf geschäftliche E-Mails, Terminplaner, Kontakte und Aufgabensynchronisation auf dem Laufenden sind. Das Handy bietet die umfangreichste mobile Implementierung von Exchange ActiveSync. Es bietet das sicherste Mobile Device Management unter den Smartphones und unterstützt die meisten Richtlinien und Einschränkungen unter den Android ActiveSync Clients und ermöglicht Kommunikation in Echtzeit mit Telefonen der Mitarbeiter, um Einstellungen per Fernzugriff zu konfigurieren, die Einhaltung der Richtlinien zu überwachen, die Sicherheit bei synchronisierten Daten zu gewährleisten und verwaltete Telefone zu sperren oder Daten zu löschen.
";2;False;0;;;Samsung Galaxy S II (i9100) DualCore Smartphone weiß;samsung-galaxy-s-ii-i9100-dualcore-smartphone-weiss;True;False;P-0020;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;439.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40651,9089699074;76;5;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000473-samsung-galaxy-s-ii-i9100-dualcore-smartphone-weis.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000474-samsung-galaxy-s-ii-i9100-dualcore-smartphone-weis.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000475-samsung-galaxy-s-ii-i9100-dualcore-smartphone-weis.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;HTC Hero;"HTC Hero ";"
HTC Hero Smartphone ohne Vertrag, ohne Branding, kein Simlock
Probiere etwas Neues. Sei Du selbst.
 
Der HTC Hero bietet Dir das ultimative HTC-Erlebnis. Du kannst dieses Smartphone wie kein anderes an Deine individuellen Bedürfnisse anpassen und machst es dadurch zu einem Mobiltelefon, das wie für Dich geschaffen ist. Es verbindet Dich leichter denn je mit den Menschen, die für Dich wichtig sind. - Denn alle Kommunikationen werden nach Personen anstatt nach Anwendungen organisiert. Der HTC Hero wird Dir - egal wo Du gerade bist und was Du gerade machst - das Leben durch seine einfache und intuitive Bedienung erleichtern. So, wie Du es Dir von Deinem Handy immer gewünscht hast!
 
Make it your Hero
Der HTC Hero ermöglicht Dir einen Level der Personalisierung, den kein anderes Smartphone bislang geboten hat. Anstatt wichtige Anwendungen hinter zahlreichen Menüstrukturen zu verstecken, kannst Du sie nun dort positionieren, wo Du direkten Zugriff hast: nämlich direkt auf einem der 7-teiligen Homescreens! Und weil HTC an die absolute Personalisierung glaubt, kannst Du auch viele Widgets mit vielfältigen Designs und in verschiedener Größe anpassen, ganz nach Deinem Geschmack. Das interaktive Erlebnis geht weiter, wenn Du z.B. einen Aktien-Ticker auf den Homescreen legst oder Dir die aktuelle Wettervorhersage für heute oder auch gleich für die nächsten fünf Tage auf einen Blick anzeigen lässt.
 
Stay close with friends
Die vernetzte Welt bietet uns zwar die Möglichkeit, mit mehr Menschen als jemals zuvor in Kontakt zu bleiben, aber den Überblick über alle Kontakte zu behalten, wird immer schwieriger. Statt umständlich eine Anwendung nach der anderen zu öffnen, um Deine Freunde zu kontaktieren, funktioniert das mit dem HTC Hero einfacher: Wenn Du Deine Kontakte aufrufst, siehst Du auf einen Blick die verschiedenen Möglichkeiten der Kontaktaufnahme und alle bisherigen Interaktionen - einschließlich der E-Mails, die Du an Deine privaten und beruflichen E-Mail-Adressen erhalten hast. Außerdem kannst Du direkt Status-Updates in Deinen Social Communities verfolgen und Dir die neuesten Fotos ansehen, die Deine Freunde gerade hochgeladen haben.
 
Discover the Unexpected
Selbst grundlegende Dinge wie die Anruf-Funktion werden Dich beim HTC Hero angenehm überraschen. Denn Du findest eine Person, indem Du ihre Telefonnummer wählst oder einfach nur die ersten Buchstaben ihres Namens eingibst. Und während Du in der Kontakt-Ansicht bist, kannst Du auch gleich einmal nachsehen, ob Dein Kontakt bald Geburtstag hat oder neue Infos oder Bilder auf Facebook oder Flickr eingestellt hat.
 
Mit dem HTC Hero kannst Du Deine Inhalte immer aus der Perspektive betrachten, die Dir gerade am besten passt. Deine Inbox ist zum Beispiel nicht nur eine Liste mit E-Mails, sondern vielmehr ein Konversations-Chat. Mails mit Anhängen kannst Du in einer separaten Dokumenten-Bibliothek ansehen. Die Fotos in Deinem Fotoalbum sind nicht nur auf Deinem Handy abgespeichert, sondern Du kannst sie via Upload auf Facebook oder Flickr auch mit Deinen Freunden teilen.
 
Suche und finde einfach alles, überall – mit Deinem HTC Hero. Anhand des Such-Buttons durchsuchst Du Tweets in Twitter, findest Personen in Deiner Kontaktliste, suchst nach E-Mails in Deinem Posteingang oder Terminen in Deinem Kalender… und selbst die sprichwörtliche Suche nach der Nadel im Heuhaufen ist so von Erfolg gekrönt.
 
 
";2;False;0;;;HTC Hero weiß;htc-hero;True;True;P-0015;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;449.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40651,7809027778;"73;2095";36;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000344-htc-hero.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000345-htc-hero.jpg;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;LG KM 900 Arena;LG KM 900 Arena;"LG KM 900 Arena
 
FM Transmitter, GPS, 5MP,WLAN 
 

brilliantes, hochauflösendes 3Zoll Touchscreen
benutzerfreundliches S-Class User Interface durch taktiles Feedback bei Tastendruck & Widgets
Dolby Mobile Surround Sound und FM Transmitter für ein einzigartiges Musikerlebnis
FM-Radio mit Senderspeicher und FMTransmitter
Lieferumfang: Gerät, Akku, Ladegerät, stereo Kabel, Headset, Bedienungsanleitung, USB Datenkabel, PC-Software ";2;False;0;;;LG KM900 Arena;lg-km-900-arena;True;True;P-0026;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;219.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40651,7531597222;"72;2095";19;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000233-lg-km-900-arena.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000234-lg-km-900-arena.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000235-lg-km-900-arena.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;HTC Touch Diamond 2;HTC Touch Diamond 2;"
HTC Touch Diamond II
 
Brillantes Design und intuitive Bedienung sorgen schon beim ersten Ausprobieren für ein faszinierendes Erlebnis.
Der HTC Touch Diamond2 liefert ein komplett neues Erlebnis mobiler Kommunikation, das die Interaktionsfähigkeit mit anderen Menschen spürbar vereinfacht.
 
In Kombination mit der neuen TouchFLO™ 3D-Oberfläche ist der HTC Touch Diamond2 das aktuell attraktivste Smartphone für Konsumenten, die auf Design und Funktion setzen.
 
Erstmals präsentiert HTC einen personenzentrischen Kommunikationsansatz: Zu jeder Kontaktperson steht die gesamte Konversationshistorie auf einen Fingerstreich zur Verfügung, unabhängig von der Art der Kommunikation wie Sprache, Text oder E-Mail.
 
Features
 
5-Megapixel-Kamera mit Autofokus
Erweitertes TouchFLO 3D für eine bessere intuitive Nutzung
3,2” WVGA LCD Touchscreen mit 480x800 Pixeln
Zoom-Leiste für präzises Hinein- und Heraus- Zoomen in Bildern, Webseiten oder Google Maps™
microSD™ (SD 2.0-kompatibel) Erweiterungs-Slot 
 
Mehr als ein Telefongespräch
In der heutigen Zeit gibt es viele verschiedene Arten der Kommunikation, doch sie haben alle etwas gemeinsam: Am anderen Ende befindet sich immer eine Person. Aus diesem Grund ermöglicht Ihnen der HTC Touch Diamond2, Ihre Kommunikation nach Personen zu organisieren – nicht nur nach der Art wie Sie kommunizieren.
 
In Ihren Kontakten befindet sich Ihre gesamte Kommunikations-Historie – egal ob E-Mail, SMS oder Telefongespräch. Es spielt keine Rolle, ob Sie während eines Gesprächs nach einer E-Mail gefragt werden oder Sie in einem Café sitzend einen Text abrufen möchten – alle Interaktionen sind nach Personen geordnet in einem Kommunikationsbaum abgelegt.
 
Erweitern Sie Ihr Blickfeld
Eine unbestrittene Tatsache bei Smartphones – ein großer Bildschirm bei einem kleinen Gerät, das ist gut. Genau darum haben wir das Display des Touch Diamond2 so groß wie möglich designt, bei gleichbleibend kompaktem Gehäuse. Genießen Sie Videos, Webseiten, Fotos und andere Abbildungen auf dem ultra-scharfen Widescreen-Display – es lässt auch das kleinste Detail erkennen. 
Schön und leistungsfähig zugleich
Das Mobiltelefon ist eines der wenigen Gegenstände, die wir heutzutage immer an unserer Seite haben. Es hilft uns nicht nur mit unseren Freunden, Geschäftspartnern und dem weltweiten Geschehen verbunden zu sein – es ergänzt uns. Der Touch Diamond2 ist Ihr perfekter Begleiter: Er hält Sie auf dem Laufenden und ist stilvolles Accessoire zugleich.
Mit seinem klaren und doch elegantem Design ist das HTC Touch Diamond 2 ein Smartphone mit Stil und Eleganz. Seine einfache Handhabung über den TouchFlo-3D- Bildschirm überzeugt. Feinste Sensoren garantieren eine empfindliche, daher schnelle Bedienbarkeit. Ein neues Erlebnis von mobiler Kommunikation ob im privaten oder im business-Bereich.
 
Die zahlreichen Funktionen sind komfortabel zu bedienen, die ausgeprägte Technik im HTC Touch Diamond 2 vereint zahlreiche Funktionen mit wenig Aufwand. Als Navigationsgerät ein zuverlässiger Wegweiser ist das HTC Touch Diamond 2 ein edler Begleiter, nicht zuletzt durch die zahlreichen Onlinefunktionen für Unterwegs der ideale Communicator.
 
";2;False;0;;;HTC Touch Diamond 2 Smartphone;htc-touch-diamond-2;True;True;P-0012;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;399.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40651,7106365741;73;36;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000198-htc-touch-diamond-2.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000199-htc-touch-diamond-2.jpg;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;HTC Touch HD;HTC Touch HD;"
HTC Touch HD (Blackstone) (UMTS, HSDPA, 5MP, Touch Screen, 3.8 Zoll Display) Smartphone ohne Branding
 
HTC – Smarte Geräte für smarte Leute / Perfekt für Sie geeignet
Bei der Entwicklung von HTC-Produkten berücksichtigen wir immer die Bedürfnisse individueller Anwender. Wenn Sie gerne Text eintippen, gibt es für Sie Geräte mit praktischen aufschiebbaren QWERTZ-Tastaturen. Mit einem unserer vielen Touch-Geräte können Sie entweder mit Ihren Fingern oder einem Stift Anwendungen bedienen und im Internet browsen. Wenn Sie sich eine hohe Leistungsfähigkeit wünschen, geben Ihnen unsere 3,5G-Geräte die Geschwindigkeit, die Sie für das Herunterladen und Streaming von Medieninhalt aus dem Internet benötigen. Wenn Sie nach einem Telefon suchen, das einfach alles kann, finden Sie in unserem Produktsortiment leistungsfähige PDA-Telefone, die Ihnen alle möglichen Funktionen für unterwegs bieten. Die Liste kann unaufhörlich fortgesetzt werden.
 
HTC glaubt nicht, dass es lediglich eine große Lösung für alle Probleme gibt. Warum sollten Sie Ihre Lebensweise auf die Funktionen eines einzelnen Produktes abstimmen? Egal welche Bedürfnisse Sie haben, mit unserer jahrelangen Erfahrung in Innovation, unserem Fachwissen und unserem Vorstellungsvermögen kann HTC Ihnen mit Sicherheit Produkte bieten, die perfekt auf Sie und Ihren Lebensstil zugeschnitten sind.
 
Führende Technologie
HTC ist ein Vorreiter in der Technologie für mobile Geräte. Wir entwickeln nicht nur Produkte mit Funktionen, die Sie haben sollten, wir entwickeln Produkte mit Funktionen, die Sie wirklich benötigen, und die Sie sich wirklich wünschen. Wir wissen, dass Sie sich ein schickes und smartes Gerät wünschen, mit dem Sie Ihre Arbeiten erledigen können, mit denen Sie jederzeit erreichbar sind und mit denen Sie auch mal etwas Spaß haben können. Dies ist der Grund dafür, warum HTC immer wieder neue Maßstäbe bei der Herstellung von Produkten setzt, die Kunden das bestmögliche mobile Erlebnis bieten können.
 
HTC hört Ihnen zu
HTC produziert Produkte, die Ihnen, unserem geschätzten Kunden, gefallen. Um dies auch wirklich zu erreichen, legen wir sehr viel Wert darauf, Ihnen zuzuhören und herauszufinden, wie Sie Ihr Leben gestalten und welche Wünsche Sie haben. Wir verfolgen nicht nur die Trends auf dem Markt sondern auch die Entwicklungen im kulturellen Umfeld. Wir nehmen uns die Bedürfnisse unserer Kunden zu Herzen und entwickeln auf effiziente Weise neue Produkte, um Ihre Wünsche in kürzester Zeit zu erfüllen.
 
Das HTC Touch HD im Detail
Genießen Sie Musikvideos, Filme und Streams, wie Sie es sich nie auf einem Mobilgerät erträumt hätten. Das Surfen im Internet wird zu einer berauschenden Erfahrung ... so als hätten Sie Ihren Laptop dabei. Und das alles auf einem hochauflösenden 3,8""-WVGA-Display, das sich nahtlos mit der berührungsempfindlichen TouchFLOTM 3D-Oberfläche vereint.
 
Dank der blitzschnellen 3.5G-Technologie erreicht Ihre Internetverbindung echte Breitbandgeschwindigkeit. In HSDPA-Netzen liefert das Touch HDTM eine Downloadgeschwindigkeit von bis zu 7,2 Mbit/s – so können Sie ohne Einschränkungen arbeiten und spielen.
 
Das neue Register „Stock“ (Aktien) informiert über aktuelle Aktienkurse, während in der Startanzeige E-Mails, Nachrichten und der Kalender nur einen Fingerzeig entfernt sind.
 
Die Routenführung bringt Sie sicher ans Ziel, Satellitenkarten weisen Ihnen den Weg und mit GoogleTM Maps wissen Sie jederzeit, wo Sie gerade sind. Auf dem breiten Display sind die Karten jetzt noch größer und schärfer. Die Anzeigesteuerung bietet eine Zoomfunktion und eine Detailansicht. So wird Navigation völlig neu definiert.
 
Zu den Highlights des Gerätes gehören:
- Kinoerlebnis für unterwegs mit 3,8 Zoll breitem WVGA-Display (480 X 800 Pixel)
- Fortschrittliche TouchFLOTM 3D -Oberfläche, die beim Navigieren durch Kontakte und Webseiten sowie Anzeigen von 
  Medieninhalten perfekt auf Fingerbewegungen reagiert
- HSDPA-Internetverbindung ermöglicht Surfen und Datentransfer mit Breitbandgeschwindigkeit.
- Google MapsTM im Breitbildformat
- 5-Megapixel-Kamera für höchste Foto- und Videoqualität
- Durch den 3,5-mm-Audioanschluss ist das Touch HDTM mit umfangreichen Audiozubehör kompatibel.
 
";2;False;0;;;HTC Touch HD Smartphone;htc-touch-hd;True;True;P-0009;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;449.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40651,6773263889;73;36;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000188-htc-touch-hd.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000189-htc-touch-hd.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000190-htc-touch-hd.jpg;1;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Sony Ericsson Xperia PLAY Smartphone;Sony Ericsson Xperia PLAY Smartphone (10,1 cm (4 Zoll) Touchscreen, 5 MP Kamera, Android OS 2.3, inkl. 7 vorinstallierten Spielen);"
Sony Ericsson Xperia PLAY
Effizientes Arbeiten und hochklassiges Spielevergnügen
Sie brauchen ein hocheffizientes, voll ausgestattetes Smartphone? Und was wäre, wenn es noch richtige Spielsteuerungselemente bieten würde? Hier ist es: Das Xperia™ PLAY. Ein PlayStation™ certified Android™ Smartphone, das Sie in die Spiele Ihrer Wahl eintauchen lassen.
 
Vorinstallierte Spiele
Auf dem Xperia™ PLAY haben Sie viele Spiele vorinstalliert, mit denen Sie Ihr Können unter Beweis stellen können. Und das ist nur der Anfang. Wählen Sie aus einem riesigen Angebot, das ständig wächst und bereits Tausende von Spielen der weltbesten Anbieter umfasst, unter anderem auch PlayStation®-Spiele. Besuchen Sie den Android Market™ und schauen SIe nach, welche Anbieter bereits Spiele bereitgestellt haben. (Vorinstalliert sind folgende Spiele: Star Battalion, Bruce Lee: Dragon Warrior, Crash Bandicoot, FIFA10, SIMS 3, Tetris)
 
Das Xperia PLAY™ ist in aller Munde. Das erste PlayStation®-zertifizierte Smartphone löst wahre Begeisterungsstürme bei den Spieleanbietern aus.
 
So, das ist nun das PSP Handy?
Einst ein Traum. Heute Realität. Das erste PlayStation certified Android™-Smartphone bietet eine unglaubliche Grafik, eine großartige Tonqualität und richtige Spielsteuerungselemente. Das Handy wird dennoch nicht ""das PSP Handy"" genannt. Wir nennen es Xperia™ PLAY.
 
Das Smartphone als Controller
Spielbegeisterte erkennen sofort die Konsolentasten. Sie wurden von demselben Team entwickelt und getestet, das auch den PS3-Controller entwickelt hat.
 
Das erste PlayStation®-zertifizierte Smartphone mit speziellen Spieletasten, L/R-Schultertasten und vier Symboltasten
4-Zoll-Multitouch-Bildschirm mit 16 Millionen Farben
Spielvergnügen wie bei einer Spielekonsole mit überragendem Stereo-Sound
Mit Snapdragon 1-GHz-CPU und dem leistungsstarken Grafikprozessor Adreno 205, der optimales Spielvergnügen garantiert
Micro SD mit 8 GB (im Lieferumfang enthalten), erweiterbar auf 32 GB
 
Multimedia-Smartphone mit Android™
Nie wieder verlaufen. Entdecken Sie Städte und Sehenswürdigkeiten mit 3D-Karten. Verwenden Sie Google Voice Search™, um Anrufe zu tätigen, Nachrichten zu schreiben usw. Mit Ihrem Xperia™ PLAY Android™ Handy brauchen Sie nicht mehr zu tippen. Geben Sie die Anweisungen einfach per Sprache ein. Darf's etwas mehr sein? Holen Sie sich alle Apps, die Sie brauchen, aus dem Android Market™.
 
Greife direkt auf die mobilen Dienste von Google™
Surfe per Sprachbefehl mit Google Voice Search™ im Internet
Mach aus deinem Smartphone im Handumdrehen eine Spielekonsole
";2;False;0;;;Sony Ericsson Xperia PLAY Smartphone;sony-ericsson-xperia-play-smartphone;True;True;P-0028;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;269.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40651,6637268519;77;35;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000573-sony-ericsson-xperia-play-smartphone.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000574-sony-ericsson-xperia-play-smartphone.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000575-sony-ericsson-xperia-play-smartphone.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;LG P970 Optimus Black Smartphone;"LG P970 Optimus Black Smartphone (10.2cm (4 Zoll) NOVA-Touchscreen, 5 MP Kamera, 9.2mm dünn, Android 2.2, 3.5mm Buchse, Wifi, GPS) schwarz ";"
Die Superlative - LG P970 Optimus Black mit NOVA Display Technologie
Neue Technologie für helles und gleichzeitig energiesparendes Display
10.2 cm (4 Zoll) Touchscreen Smartphone mit Android 2.2 Betriebssystem, 2 Megapixel Frontkamera, WiFi (b/g/n standards).
 
Superflach, superhell und super energiesparend: Das neue Android-Modell LG P970 OPTIMUS BLACK steht für eine neue Form der Superlative bei Smartphones. Das NOVA-Display mit einer Bildschirmdiagonale von 10,2 Zentimetern garantiert die hellste, klarste und deutlichste Anzeige auf einem Mobiltelefon-Display — selbst bei direkter Sonneneinstrahlung. Einen Superlativ bringt LG auch mit dem Design des neuen Android-Modells: Mit nur 9,2 Millimetern ist das LG P970 OPTIMUS BLACK eines der dünnsten Smartphones auf dem Markt.
 
LG’s NOVA-Technologie — ein Display-Novum in Sachen Helligkeit…
„Unser LG P970 OPTIMUS BLACK ist der Inbegriff des innovativen Smartphones. Die Kombination aus anspruchsvoller Technologie sowohl beim Display als auch beim Design machen unser neues Android-Modell zu einem absoluten Must-Have“, so Gunter Thiel, Head of Mobile Marketing bei der LG Electronics Deutschland GmbH.
Mit einer Leuchtdichte von 700cd/m² (Candela pro Quadratmeter) setzt das NOVA-Display neue Standards: Sehr gute Smartphones-Displays kommen aktuell auf bis zu 480 cd/m². Dank seiner größeren Helligkeit und reinen Weißtönen, die eine kontrastreiche Schwarz-Weiß-Darstellung ermöglichen, bietet das neue Smartphone den Anwendern mehr Komfort beim Surfen im Internet, Lesen von E-Mails und Verfassen von Dokumenten.
 
… und im Stromverbrauch
Das NOVA-Display zeigt auch seine „grüne“ Seite: Es verfügt nicht nur über eine höhere Leuchtkraft, sondern sorgt darüber hinaus für eine deutliche Reduzierung des Energieverbrauchs. Im Vergleich zu einer herkömmlichen LCD-Anzeige benötigt das Display 50 Prozent weniger Strom. Auch AMOLEDs verbrauchen doppelt so viel Energie wie ein NOVA-Display für die Darstellung eines hauptsächlich weißen Bildschirms, also des Farbschemas, das am häufigsten beim Browsen im Web genutzt wird. In Verbindung mit dem 1500-mAh-Akku des LG P970 OPTIMUS BLACK steht den Nutzern genügend Energie für ihre täglichen Anforderungen selbst bei maximaler Helligkeitseinstellung zur Verfügung.
 
Superlative auch in Sachen Style …
Dank seinem ultraflachen 9,2 Millimetern Design setzt das LG P970 OPTIMUS BLACK mehr als nur stylishe Akzente: Mit einem Gewicht von gerade mal 109 Gramm, einer eleganten Linienführung und abgerundeten Kanten wird das neue Smartphone zu einem wahren Handschmeichler. Mit der raffinierten Rückseite des Geräts, die nach Außen flach zuläuft, wirkt das Profil von 6,0 Millimetern noch einmal schlanker. Ein unverwechselbares Kennzeichen des LG P970 OPTIMUS BLACK ist das minimalistische Design — selbst der Lautsprecher ist nahezu unsichtbar im Rahmen des Telefons integriert.
 
… und Funktionen: Wi-Fi Direct, Apps und vieles mehr
Als weltweit erste Gerät unterstützt das LG P970 OPTIMUS BLACK Wi-Fi Direct1 für die schnelle Übertragung von Daten zu anderen Geräten. Zudem bietet das neue Android-Smartphone eine Reihe von intelligenten Funktionen für den einfachen und schnelleren Zugriff auf relevante Apps und Inhalte. Das OPTIMUS User Interface (UI) 2.0 ermöglicht den Anwendern den direkten Zugriff auf Nachrichten, E-Mails und verpasste Anrufe mit nur einer Fingerberührung auf dem gesperrten Display. Die Gestensteuerung unterstützt auch intuitive Kommandos wie Hochheben, Schütteln und Antippen, um Anrufe entgegenzunehmen, in den Kameramodus zu schalten oder Musik zu genießen. Ebenfalls ein Novum ist die Ausstattung mit einer Frontkamera mit 2 Megapixeln Auflösung.
(1Für die Aktivierung von Wi-Fi Direct™ auf dem Smartphone ist eine Anwendung erforderlich, die in der erste Hälfte des Jahres 2011 im Android Market zum Download zur Verfügung gestellt wird.)
 
Alle Features des LG P970 OPTIMUS BLACK sind auf der Android 2.2 Froyo Plattform mit der Möglichkeit zum zukünftigen Upgrade auf Android 2.3 Gingerbread verfügbar. Nach einem Upgrade auf Android Gingerbread können die Nutzer Videogespräche mit höherer Qualität über die 2- Megapixel-Frontkamera des LG P970 OPTIMUS BLACK führen.
 
Beschreibung der Features
 
2 MP Front-Kamera
Warum auf Bildqualität für sich selbst verzichten? Mit der 2 MP Front-Kamera haben Sie jetzt eine noch höhere Auflösung für die Front-Kamera zur Verfügung. Für Selbstporträts und Videotelefonie in noch höherer Qualität.
 
Volle Flash-Unterstützung und Android Market
Dank des Android Betriebssystems haben Sie uneingeschränkten mobilen Zugriff auf das Internet. Ihr Smartphone unterstützt sämtliche Flash-Formate und setzt dem Online-Spaß keine Grenzen. Ausserdem haben Sie die Möglichkeit, auf Apps zuzugreifen und können Sich beispielsweise den Google Navigator kostenlos herunterladen. So haben Sie ein Navigationsgerät in Ihrem Handy.
 
Im gigantischen Online Store Android Market stöbern Sie vom Handy aus durch über 200.000 Apps für Social Networks, Games, Lifestyle, Shopping und mehr. Oder Sie finden genau die App, die Sie schon lange gesucht haben. So individualisieren Sie Ihr Smartphone genau nach Ihren Wünschen und machen Ihren neuen Begleiter zu einem Spezialisten auf jedem Gebiet.
 
G-Key
Mit dem G-Key bedienen Sie Ihr Smartphone noch intuitiver. Bei aktiviertem G-Key nehmen Sie eingehende Anrufe mit einer einfachen Bewegung ihres LG an, scrollen zwischen Fotos oder wechseln Anwendungen wörtlich im Handumdrehen.
 
NOVA Display
Mit einem NOVA-Display müssen Sie nie wieder nach einem schattigen Platz suchen, um etwas erkennen zu können. Ob in völliger Dunkelheit oder direkter Sonneneinstrahlung, das NOVA Display bietet Ihnen jederzeit perfekte Klarheit und eine ungekannte Farbechtheit. Es ist dabei bis zu 50% energieeffizienter als vergleichbare LCD-Displays.
 
Wi-Fi Direct
Mit der Wi-Fi Direct Technik übertragen Sie Daten zwischen Wi-Fi-Geräten ganz simpel und schnell, ohne einen externen Acces Point zu benötigen. Wi-Fi Direct zeichnet sich dabei nicht nur durch die einfache Bedienung sondern darüber hinaus auch durch die extrem hohe Übertragungsrate aus: 20 mal schneller als über eine herkömmliche Bluetooth-Verbindung.
";2;False;0;;;LG P970 Optimus Black Smartphone;lg-p970-optimus-black-smartphone;True;True;P-0023;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;189.0000;189.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40651,6470023148;"72;2095";19;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000259-lg-p970-optimus-black-smartphone.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000260-lg-p970-optimus-black-smartphone.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000261-lg-p970-optimus-black-smartphone.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Motorola Milestone 2 Smartphone;Motorola Milestone 2 Smartphone (9,4 cm (3,7 Zoll) Touch-Display, 5 Megapixel Kamera, 1Ghz, 16GB, Android 2.2);"
Motorola Milestone 2 - Slider Smartphone mit QWERTZ Tastatur (9,4 cm (3,7 Zoll) Touch-Display, 5 Megapixel Kamera, 1Ghz, 16GB, Android 2.2)
 
Motorola Milestone 2 - Ansichten
MILESTONE™ 2 mit MOTOBLUR™
Das ultraflache Slider - Smartphone mit Android™ 2.2 und ausklappbarer QWERTZ-Tastatur bietet im Vergleich zu seinem Vorgänger noch mehr Geschwindigkeit, noch mehr Verbindungsmöglichkeiten, noch mehr Messaging, noch mehr Speicher, noch mehr Web-Erlebnisse, noch mehr Multimedia, den Adobe® Flash®-Player 10.1 und ein Plus an Personalisierung.
 
Das Hochleistungs-Smartphone besitzt einen 1 GHz-Prozessor, der alle Eingaben blitzschnell umsetzt, selbst wenn viele Anwendungen parallel laufen oder eine Vielzahl von Webseiten geöffnet sind. E-Mails oder Nachrichten lassen sich dank verbesserter QWERTZ-Tastatur mit noch größeren Tasten und sehr gutem Tastendruck schneller eingeben. MILESTONE 2 ist bestens auf die Anbindung an das firmeneigene IT-Netz eingestellt. Zusätzliche Kontrollmöglichkeiten erhöhen die Sicherheit in Firmennetzwerken. Das Smartphone lässt sich außerdem als persönlicher WLAN-Hotspot einsetzen, über den sich bis zu fünf Nutzer mit ihren Geräten im Internet einloggen können.
 
MOTOBLUR synchronisiert DatenMOTOBLUR™ erleben
 
Das MILESTONE 2 ist mit der neuesten MOTOBLUR-Version, Motorolas mobilem Dienst für soziale Netzwerke, ausgestattet.
MOTOBLUR fasst alle verfolgten Threads, Freunde und freigegebene Posts, Links oder Fotos in einem einzigen Datenstrom zusammen.
MOTOBLUR synchronisiert Daten von Gmail, Arbeits-E-Mails, Facebook, Myspace und Twitter. Dabei werden Ihre Daten sogar gesichert, d. h. Sie können auch bei einem Verlust des Telefons die Informationen auf einem neuen Telefon von Motorola mit MOTOBLUR wiederherstellen, wenn Sie Ihren Benutzernamen und ein Kennwort eingeben.
 
 
Fotos und VideosBilder und Videosequenzen in großartiger Qualität

Die 5-MP-Kamera mit Zoom, Autofokus, Blitzlicht und Bildstabilisation ist ideal für die Aufnahme von Bildern und Videosequenzen in großartiger Qualität. Content posten, runterladen oder synchronsieren mit Motorola Media Link. Das Motorola MILESTONE 2 nimmt HD-Videos mit 720p-Signal auf und gibt diese auch in HD wieder. Und das Beste: Da das MILESTONE 2 nach dem DLNA-Standard (Digital Living Network Alliance) arbeitet, können die Videos oder andere Multimedia-Inhalte anschließend mit DLNA-kompatiblen Geräten ausgetauscht werden.
 
Multimedia-Inhalte
Internet - Nachrichten - Multimedia und Online-Communitys
Dank Adobe Flash Player 10.1 kann man außerdem Angebote Tausender Webseiten so sehen, wie sie sein sollen. Ein weiteres Highlight ist der vernetzte Mediaplayer, der neben der Musik die Songtexte sowie zusätzliche Informationen zum Künstler zugänglich macht und Applikationen bietet, um Empfehlungen zu geben und auszutauschen.
 
Mit einem internen Speicher von 8 GB bietet MILESTONE 2 jede Menge Speicherplatz für Multimedia-Inhalte. Dieser lässt sich über die mitgelieferte 8 GB microSD-Karte erweitern. Wem das nicht genügt, kann microSD-Karten von bis zu 32 GB verwenden.
 
Eine Reihe von Google™-Applikationen wie Google Search™, Google Maps™, Google Mail™ und YouTube™ runden die Geräteausstattung ab. Außerdem bietet der Android Market™ Zugang zu Tausenden Apps.
 
Smartes Zubehör
Das MILESTONE 2 wird mit einer 8 GB-microSD-Karte und einem Headset ausgeliefert. Nutzer können die Motorola Media Link Software kostenlos herunterladen, um Musik oder andere Multimedia-Inhalte ganz einfach zwischen dem Smartphone und dem PC auszutauschen
 
 
Zubehör: Multimedia-StationMit weiterem optionalem Zubehör läuft das MILESTONE 2 zuhause, im Auto oder im Büro zur Höchstform auf:
Die optionale Autohalterung ist startklar für die Straße. Sobald das Handy in der Autohalterung steckt, stellt es auf den Automodus um. Mit einer Berührung sind alle Funktionen zugänglich, egal, ob Kontaktauswahl über die Freisprecheinrichtung, Musik, Internetradio, Podcasts, Google Maps™ mit Navigation™ oder vieles mehr. Das Handy lässt sich einfach über das Ladekabel aufladen, das an die Autohalterung angeschlossen werden kann. Mit integriertem GPS und der MOTONAV Schritt-für-Schritt-Navigation gelangt man immer ans Ziel
 

MILESTONE 2 verwandelt sich in der komfortablen Multimedia-Station in eine Schaltzentrale für Filme, Musik, Bilder oder in einen Digitalwecker. Im Desktop-Modus kann das Gerät mit den Wunsch-Apps individualisiert werden. Und das alles, während das Milestone 2 automatisch auflädt. Die Multimedia-Station ist auch mit dem ersten MILESTONE kompatibel.
";2;False;0;;;Motorola Milestone 2 Smartphone;motorola-milestone-2-smartphone;True;True;P-0036;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;499.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40651,6393981481;"75;2095";16;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000424-motorola-milestone-2-smartphone.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000425-motorola-milestone-2-smartphone.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000426-motorola-milestone-2-smartphone.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;BlackBerry Curve 8520;BlackBerry Curve 8520 schwarz;"
BlackBerry Curve 8520
  
 
QWERTZ-Tastatur


Das BlackBerry Curve 8520 Smartphone passt genau in Ihre Hand, in Ihre Tasche - und in Ihr Leben.
Mit dem schlanken und leichten Design liegt es gut in der Hand und bietet hohen Bedienkomfort.
Nachrichten können mit dem BlackBerry Curve 8520 Smartphone mit der vollständigen QWERTZ-Tastatur
einfach und schnell versendet werden. Jeder Buchstabe ist einer eigenen Taste zugewiesen.
Dies erleichtert die Eingabe und fühlt sich ganz natürlich an.
Das helle Display sorgt mit mehr als 65.000 Farben für eine brillante Anzeige, ganz egal, ob Sie sich E-Mails,
Textnachrichten, Videos oder Bilder ansehen.
 
Das BlackBerry Curve 8520 Smartphone ist unmittelbar mit Apple-Computern kompatibel.
Synchronisieren Sie Ihre Kontaktlisten, Kalender, Termine und Notizen mit den Anwendungen,
die Sie am häufigsten nutzen. Wenn Sie die BlackBerry Desktop Software auf Ihrem BlackBerry
Curve 8520 Smartphone verwenden, ist das BlackBerry Smartphone ganz ähnlich zu bedienen
wie Ihr Apple-Computer.
Schlankes vereinfachtes Design
Spezielle Medientasten
Verbindung mit BlackBerry App World
Videokamerafunktionen (2.0 Megapixel-Digitalkamera)
Unterstützung von Apple-Computern
";2;False;0;;;BlackBerry Curve 8520 Smartphone ohne Vertrag;blackberry-curve-8520;True;True;P-0033;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;269.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40651,6285069444;"70;2095";43;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000488-blackberry-curve-8520.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000489-blackberry-curve-8520.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000490-blackberry-curve-8520.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;LG KP500 Cookie;"LG KP500 Cookie schwarz ";"
LG KP500 Cookie
 
LG KP500 Cookie Smartphone
Touchscreenhandy mit iPhone-Feeling für Einsteiger!
Das Full-Touchscreen-Telefon LG KP500 überzeugt durch innovative Technologien und Features, wie sie bislang nur High-End-Telefonen mit kompletter Touchscreen-Bedienung vorbehalten waren.
 
Touchscreen für alle
Die Optimierung der Benutzeroberfläche stand bei der Entwicklung des LG KP500 im Mittelpunkt. Die Onscreen-QWERTZ-Tastatur wird eingeblendet, sobald der Benutzer das LG KP500 quer hält, und das Auto- Rotating-Display zeigt Bilder oder Dokumente immer in der passenden Ausrichtung an, egal wie man das Handy hält.
 
Spielspaß
Darüber hinaus bietet das LG KP500 auch noch Bewegungssensor-Spiele, die für ein aktiveres und spannenderes Spielerlebnis sorgen, indem der Benutzer das Mobiltelefon in die gewünschte Richtung dreht oder neigt.
 
Intuitive Bedienung
Dank seiner intuitiven Benutzeroberfläche kann das LG KP500 mit den klaren Symbolen auf dem 3-Zoll-Display sofort von jedermann verwendet werden. So ist es auch ganz einfach, den Kontakt zu Freunden zu halten.
 
Kurzwahlfunktionen über Icons
Über die innovative Bedienoberfläche kann der Benutzer das Foto von Freunden der entsprechenden Kurzwahl zuordnen und muss dann lediglich zu dem Bild des gewünschten Gesprächspartners blättern und es berühren, um ihn anzurufen.
 
3,0-Megapixel-Digitalkamera
Das großzügige 3""-Display bietet darüber hinaus nicht nur genügend Platz für eine komfortable Bedienung, sondern auch die Möglichkeit Videoclips, eigene Filmchen (max.320 x 240 Pixel, bis zu 24fps) oder Fotos zu betrachten. Diese können mit der 3,0-Megapixel-Digitalkamera (2-faches Digital-Zoom) geschossen und auch per Internet versendet werden.
 
Unterhaltung an Bord
Radio und MP3-Player befinden sich ebenfalls an Bord. Für einfachen Datentransfer besitzt das LG KP500 sowohl einen USB-Anschluss, als auch eine Bluetooth-Anbindung.
 
Reichhaltiger Lieferumfang
Geliefert wird das LG KP500 in schwarzer Farbausführung inklusive Akku, Ladegerät, Stereo-Kabel-Headset, Bedienungsanleitung, USB-Datenkabel, PC-Software und Styluspen.
";2;False;0;;;LG KP500 Cookie;lg-kp500-cookie;True;True;P-0022;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;139.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40651,569375;"72;2095";19;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000247-lg-kp500-cookie.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000248-lg-kp500-cookie.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000249-lg-kp500-cookie.jpg;1;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Sony Ericsson Satio;Sony Ericsson Satio;"
Sony Ericsson Satio
 
Satio - Erlebe Entertainment in nicht für möglich gehaltenen Farbdimensionen.
Das Satio bringt Technik und Ästhetik auf völlig neue Weise zusammen und ist mit einer 12,1 Megapixel Kamera ausgestattet.
Lass Bilder sprechen Mit den einzigartigen Touch Panels tippst du dich direkt in deine beste Musik und deine Lieblingsvideos.
Die leistungsfähige Touchscreen-Kamera liefert dir gestochen scharfe Bilder. Jede Aufnahme ein Meisterstück.
Zum Scharfstellen tippen

Die 12,1 Megapixel Kamera mit Xenon-Blitzlicht und intuitivem manuellen Fokus liefert hochaufgelöste Aufnahmen, die auch auf einem großen Bildschirm beeindrucken.
The Magic Touch
Auf dem Sony Ericsson Satio holst du deine Lieblingsinhalte mit nur einer Berührung auf den Bildschirm.
Ob TV-Serien, Handyvideos, Podcasts oder Musik: Mit dem genialen Fulltouch-Medienmenü dieses beeindruckenden Entertainment-Handys tauchst du direkt ein.
Widescreenwunder
Die 16 Millionen Farben auf dem Sony Ericsson Satio machen Videos und Fotos zum Augenschmaus.
Auf dem gestochen klaren 3,5-Zoll-Bildschirm im 16:9-Format siehst du sie genau so, wie sie gedacht sind.
Symbian OS
Ein offenes Betriebssystem für Mobilgeräte, das Ihnen den Download neuer Anwendungen auf Ihr Handy ermöglicht
TFT-Touchscreen mit 360x640 Pixel und 16,777,216 Farben
unterstützte Netze: GSM/GPRS/EDGE 850/900/1800/1900 UMTS/HSPA 900/2100
12.1 Megapixel mit Autofokus und Bildstabilisator
Betriebssystem: Symbian OS
Lieferumfang:
Sony Ericsson Satio, Verpackung, Akku, Ladegerät, Bedienungsanleitung, Headset, Datenkabel, Handytasche, TV Kabel, Bedienstift
";2;False;0;;;Sony Ericsson Satio;sony-ericsson-satio;True;True;P-0029;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;299.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40651,4580324074;77;35;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000415-sony-ericsson-satio.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000416-sony-ericsson-satio.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000417-sony-ericsson-satio.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Blackberry Bold 9700 QWERTZ;"Blackberry Bold 9700 QWERTZ ";"
Blackberry Bold 9700 QWERTZ
 
Schlank, smart und beeindruckend: Das Flagschiff Blackberry Bold 9700!
 
 
Das Blackberry Bold 9700 ist ein Blackberry Smartphone mit vollständiger QWERTZ-Tastatur in edlem Schwarz!
Es kombiniert praktische Funktionen wie eine 3,2-Megapixel-Autofokuskamera samt Bildstabilisator und Blitz mit
dem Bedienkomfort eines sensitiven Trackpads, das eine mühelose Steuerung aller wichtigen Funktionen per
Fingertip ermöglicht. Im Gegensatz zu seinen Vorgängern wurden behutsame Modifikationen bei der Gestaltung
des User-Interface, der Anordnung von Bedienelementen und technischer Auslegung von Media-Player und
Stereo-Lautsprechern vorgenommen. Ansonsten wartet dieses Smartphone mit bewährten Attributen auf,
darunter geschwungenes und harmonisches Design, sowie ein großes helles Display, das mit seinen brillanten
Farben Webseiten, Fotos, Spiele und Videoclips optimal darstellt.
Smartphone mit hochauflösendem 2,44¿-Farbdisplay mit 480 x 360 Pixeln und mehr als 65.000 Farben
Bedienfreundliches Touchpad und vollständige, beleuchtete QWERTZ-Tastatur
3,2 Megapixel-Digitalkamera mit Autofokus, Bildstabilisierung und 2-fach Digitalzoom
Integrierter A-GPS-Empfänger
Lieferumfang:
Akku, Ladegerät, Stereo-Kabel-Headset, Bedienungsanleitung, USB Datenkabel und PC-Software
";2;False;0;;;"Blackberry Bold 9700 QWERTZ ";blackberry-bold-9700-qwertz;True;True;P-0032;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;499.0000;499.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40651,4502777778;"70;2095";43;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000403-blackberry-bold-9700-qwertz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000404-blackberry-bold-9700-qwertz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000405-blackberry-bold-9700-qwertz.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Samsung Galaxy S Super Clear LCD (i9003) Smartphone;"Samsung Galaxy S Super Clear LCD (i9003) Smartphone (10,1 cm (4 Zoll) Display, Touchscreen, 5 Megapixel Kamera) schwarz ";"
Überirdisch leistungsstark.
Eine Leistungsklasse für sich, das ist das Samsung Galaxy S Super Clear LCD (i9003). Highlight des eleganten Android™-Smartphones ist der extragroße Super Clear LCD-Touchscreen. Hier wird das Betrachten von Videos zum mobilen Kinoerlebnis. Auch das Surfen im Internet geht dank großem Display und Multitouch-Zoom leicht von der Hand. Das Schreiben von E-Mails und SMS gelingt unkompliziert dank Swype®-Texteingabe. Zahlreiche aktuelle und nützliche Apps stehen im Android Market™ zum Download bereit. Die integrierte Google Maps Navigation™ führt ans gewünschte Ziel. Ein erstklassiges Zusammenspiel von Hardware und Funktionen leistet sein Übriges für ein ausgezeichnetes Nutzererlebnis auf höchstem Niveau! Das Samsung Galaxy S Super Clear LCD - überirdisch leistungsstark und galaktisch gut.
 
Unvergessliche Bildqualität
Das Super Clear LC-Display beeindruckt durch seine ausgeprägte Farbtreue und ist deutlich heller und weniger anfällig für reflektierendes Licht als konventionelle LC-Displays. Eine Luftpolsterschicht zwischen Bildschirm und berührungsempfindlicher Schicht des Touchscreens besteht nicht, da die Berührungssensoren direkt auf dem Display angebracht sind. Dies sorgt nicht nur für die sichtbar bessere Farbdarstellung, sondern auch für höhere Schärfe und erlaubt dünnere Displaybauweisen.
 
In bester Kommunikation
Wollen Sie selbstgedrehte Videos oder Bilder mit anderen teilen, gelangen diese auf direktem Wege über das Mobilfunknetz in Social Communities wie zum Beispiel Facebook®, Twitter ™oder MySpace™ – ein Antippen des Touchscreens genügt. Das interaktive Telefonbuch hält Sie übersichtlich darüber auf dem Laufenden, was Ihre Freunde in den Sozialen Netzwerken posten. Ohne, dass Sie deren Profile einzeln aufrufen müssten. Ein Blick genügt.
 
Schnelle Texteingabe
Von den Erfindern der automatischen Textvervollständigung T9 kommt mit Swype® die Revolution der Texteingabe über Touchscreens. Texte werden nicht Buchstabe für Buchstabe eingegeben, sondern einzelne Worte werden ohne abzusetzen mit dem Finger über die virtuelle Tastatur nachgefahren. Texte lassen sich so bis zu 1,5-mal schneller verfassen. Bei mehrdeutigen Eingaben bietet Swype® eine Übersicht in Frage kommender Begriffe. Typische Rechtschreibfehler werden dabei automatisch korrigiert.
 
Kabelloser Datenaustausch
Multimediainhalte bringen Sie spielend leicht auf DLNA™-kompatible Geräte wie Fernseher, PCs und Notebooks. Dank DLNA™-Standard AllShare™ komplett kabellos und ohne lange Einrichtung. Sollte Ihr Fernseher nicht DLNA™-tauglich sein, erweitert das optional erhältliche Multimedia Gateway WMG160 diesen mit der entsprechenden Funktionalität.
 
Mobil arbeiten
ThinkFree® bietet auch unterwegs Zugriff auf lokal oder online gespeicherte Office-Dokumente. Diese stehen zur Ansicht und zur Bearbeitung zur Verfügung.
";2;False;0;;;Samsung Galaxy S Super Clear LCD (i9003) Smartphone;samsung-galaxy-s-super-clear-lcd-i9003-smartphone;True;True;PD-01071;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;469.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40651,4194212963;76;5;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000623-samsung-galaxy-s-super-clear-lcd-i9003-smartphone.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000624-samsung-galaxy-s-super-clear-lcd-i9003-smartphone.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000625-samsung-galaxy-s-super-clear-lcd-i9003-smartphone.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;HTC Desire HD;"HTC Desire HD Smartphone (10,9 cm (4.3 Zoll) Touchscreen, 8MP Kamera, Android OS 2.2, HSPA) Maduro Brown ";"
Innovation, die macht was Sie wollen
Das HTC Desire HD ermöglichtmit der neuesten Technologie, einem 10,9 cm Touchscreen und dem bislang schnellsten Prozessor ein besonderes Interneterlebnis. Es ist mit Android™ 2.2 und der neuesten Version von HTC Sense™ ausgestattet.
 
Ein 10,9 cm WVGA Touchscreen
Der große Touchscreen eigent sich perfektzum Anschauen von Videos, Filmen und Fotos sowie zum Surfen im Internet. Videos können mit einer Auflösung von 720p aufgenommen und in HD-Qualität auf Ihrem TV wiedergegeben werden. Musik wird ganz einfach auf den internen Speicher oder eine SD-Karte übertragen.
 
Das ultimative Interneterlebnis
Die Kombination aus dem 10,9 cm Touchscreenund dem 1 GHz-Prozessor sorgt für das ultimative Interneterlebnis. Sie können mehrere Websites gleichzeitig öffnen und diese parallel nutzen, genau so, wie Sie es von Ihrem PC gewöhnt sind. Die Textanpassung sorgt dafür, dass sich der Text beim Hineinzoomen in eine Website automatisch an das Display anpasst, so dass Sie nicht mehr scrollen müssen. Dank Flash 10.1-Unterstützung werden alle Websites so angezeigt, wie sie aussehen sollen.
 
Mit nur einem Fingertipp...
...Ihre Freunde erreichen
Mit dem Favoriten-Widget können Sie direkt auf Ihrem Homescreen verschiedene Kontaktgruppen mit Freunden oder Kollegen anlegen. Ein Anruf, eine SMS oder eine E-Mail sind dann nur noch einen Fingertipp entfernt.
 
...alle Anwendungen oder Apps bedienen
Sie können jede beliebige Anwendung oder App auf dem 7-teiligen Homescreen platzieren und nach Belieben anordnen, indem Sie sie einfach per Drag & Drop dort hinziehen. So ist alles, was Ihnen wichtig ist, immer nur einen Fingertipp entfernt.
 
Auf Facebook, Twitter und Flickr gleichzeitig zugreifen
Mit Friend Stream sehen Sie alle neuen Facebook-Updates, Tweets und Flickr-Fotos Ihrer Freunde in einer Ansicht, die sich automatisch aktualisiert. Und wenn Sie Ihre eigenen Profile in diesen Sozialen Netzwerken aktualisieren wollen, können Sie das in nur einem Schritt erledigen. 
 
Schöne Momente Festhalten
Mit der 8 Megapixel Kamera erzielen Sie erstaunliche Aufnahmen. Eine hohe Auflösung, großartige Farben und eine Vielzahl an Einstellungsmöglichkeiten bringen ein hohes Maß an Professionalität in Ihre Aufnahmen. Im dunkler Umgebung helfen Ihnen 2 LED-Blitze, immer alles im Bild zu haben. Und auch Videos erscheinen nun in HD-Auflösung. Erfassen Sie Ihre nächste Geburtstagsparty, die Firmenfeier oder Ihre Freunde in 720p Qualität.
Sehen Sie alles auf einem großen Display
Vorbei sind die Zeiten, in denen Sie Texte auf winzigen Displays entziffern mussten und die entscheidenden Informationen übersehen haben. Auf dem 10,9 cm großen Display des HTC Desire HD genießen Sie ein wahrhaft großartiges Interneterlebnis. Mit Features wie der gestochen scharfen Textdarstellung und der brillanten Wiedergabe von Fotos und Videos ist das HTC Desire HD wie dafür geschaffen, Ihre Lieblingswebsites, YouTube-Clips und Facebook-Fotos optimal wiederzugeben.
 
Ein Handy, das Sie nicht verlieren können
Mit HTC Sense™ können Sie Ihr Handy aus derFerne über ein sicheres Web-Portal steuern. Sie können es anweisen zu klingeln, selbst wenn es stumm geschaltet ist, um es wiederzufinden, oder Sie sperren es und löschen alle Inhalte, falls es gestohlen wurde. Sie können eine Nachricht an Ihr Handy senden, in der Sie den Finder um die Rückgabe bitten. Kontakte, SMS und MMS können gesichert werden, sodass sie einfach wieder hergestellt werden können.
";2;False;0;;;HTC Desire HD Smartphone;htc-desire-hd;True;True;;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;3,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;299.0000;299.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40651,414375;"73;2095";36;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000621-htc-desire-hd.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000622-htc-desire-hd.jpg;;1;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;HTC HD7;"HTC HD7 Smartphone (10,9 cm (4,3 Zoll) Touchscreen, Windows Phone 7, 5MP Kamera, GPS, Dolby Mobile, 8 GB interner Speicher, ohne Branding) schwarz ";"
Mobiles Entertainment in High Definition
Das HTC HD7 ist das ultimative Handy für die Wiedergabe von Filmen. Denn durch das Widescreen-Display, den hochwertigen Klang und den großen Speicher erleben Sie auch unterwegs perfektes Kino.
 
Großes Display und toller Klang
Genießen Sie Ihre Filme auf dem riesigen 10,9 cm Widescreen-Display. Dabei müssen Sie Ihr Handy nicht die ganze Zeit in der Hand halten – klappen Sie einfach den Ständer aus und lehnen Sie sich bequem zurück. Durch die Dolby Mobile-Technologie erleben Sie auch unterwegs einen bislang unerreichten Klang in Kinoqualität. Mit Zune® haben Sie ein perfektes Mediencenter, denn damit können Sie auch unterwegs Inhalte herunterladen und diese mit Ihrem PC synchronisieren. 8-16 GB integrierter Speicher sorgen für genug Platz, um all Ihre Filme, Musik und Spiele überallhin mitzunehmen.
 
Neue Features mit Windows Phone 7
Freuen Sie sich darauf, mit weniger Bedienschritten mehr zu erledigen. Nutzen Sie den Windows® Phone Marketplace für den schnellen, bequemen Einkauf und besuchen Sie den HTC Hub für weitere Windows® Apps, die für HTC-Nutzer kostenlos sind. Langeweile ist dank Xbox Live® Gaming auf Ihrem Handy kein Thema mehr.
 
Der Mensch an erster Stelle
Auf dem HTC HD7 finden Sie die gesamte Kommunikation mit Ihren Kontakten an einem Ort. So haben Sie direkt Zugriff auf Facebook®- und Windows® Live-Updates und Fotos, SMS und MMS, E-Mails und Anrufe. Die Personen, die Sie zuletzt kontaktiert haben, werden Ihnen auch zuerst angezeigt oder Sie gehen alternativ Ihre ganze Kontaktliste durch.
 
Momente festhalten und teilen
Mit der integrierten 5 Megapixel Kamera halten Sie jeden Augenblick fest. Ob Firmenveranstaltungen, Geburtstagsfeiern, Trips durch die Natur - Ihr HTC HD7 lässt Sie nie im Stich. Der eingebaute Blitz hilft Ihnen, selbst an dunklen Orten ein scharfes Bild zu erhalten. Direkt nach der Aufnahme, können Sie dieses auf einer der unzähligen Social Network Seiten veröffentlichen und so mit Ihren Freunden und Bekannten teilen.Mit der Videofunktion zeichnen Sie verblüffende HD-Videos mit 720p auf
";2;False;0;;;HTC HD7 Smartphone;htc-hd7;True;True;PD-01069;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;3,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;299.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40651,4104166667;73;36;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000619-htc-hd7.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000620-htc-hd7.jpg;;1;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Blackberry Bold 9000;Blackberry Bold 9000 black;"
Blackberry Bold 9000  
 
 
WLAN, GPS, QWERTZ-Tastatur, Kamera mit 2 MP, MP3-Player

 
Das BlackBerry Bold Smartphone ist Innovation pur
Mobile Komplettlösung mit hinterleuchteter QWERTZ (Tastatur), beweglichem Trackwheel und 480 x 320 Pixel Display
 
Verfügbare Funktionen:
Mobile E-Mail, Organizer, Mobiles Internet, Telefon, Kamera, Videoaufnahme, Media Player, Zugriff auf Unternehmensdaten, SMS, MMS, GPS & Blackberry Maps
Erweiterbarer Speicherplatz - unterstützt microSD-Karten, 1 GB integrierter + 128 MB Flash-Speicher
Unterstützt Tri-Band-HSDPA, Quad-Band-GSM/EDGE 3G und WLAN 4 und kann als Hochgeschwindigkeits-Modem mit 3,6 MB/s eingesetzt werden
";2;False;0;;;Blackberry Bold 9000;blackberry-bold-9000;True;True;P-0031;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;459.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40651,1651736111;"70;2095";43;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000370-blackberry-bold-9000.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000371-blackberry-bold-9000.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000372-blackberry-bold-9000.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Blackberry Curve 8900;Blackberry Curve 8900;"
Blackberry Curve 8900 
 
 
WLAN, GPS, QWERTZ-Tastatur, BlackBerry Maps, Organizer, Kamera mit 3,2 MP, MP3-Player
 
 
Deutsche Tastatur im QWERTZ-Layout mit beweglichem Trackball, ESC- und Menütaste zur intuitiven Menüsteuerung, hochauflösendes 2,44 Zoll-Farbdisplay mit 480x360 Pixel
 
Verfügbare Funktionen:
WLAN-kompatibel IEEE 802.11b/g, Integrierter GPS-Empfänger, Media Player für Audio und Video, Videoaufzeichnung, BlackBerry Maps, Mobile E-Mail, Organizer, Browser, Mobiltelefon, Zugriff auf
Unternehmens-EDV, SMS/MMS
 
3,2 Megapixel-Kamera mit Autofokus, automatischem Blitz und Bildstabilisierung, Videofunktion
Netzkompatibilität: GSM 900/1800/GPRS (Europa, Asien, Australien, Südamerika (teilw.)), CDMA 850/1900/GPRS (Nordamerika), EDGE
";2;False;0;;;Blackberry Curve 8900;blackberry-curve-8900;True;True;P-0035;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;359.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40651,1558101852;70;43;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000365-blackberry-curve-8900.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000366-blackberry-curve-8900.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000367-blackberry-curve-8900.jpg;1;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;HTC Touch 2;HTC Touch 2;"
HTC Touch 2 
 
Das HTC Touch2 macht es Ihnen leicht
 
  
Bleiben Sie in Kontakt mit Ihren Freunden, finden Sie heraus, was es bei Facebook Neues gibt, rufen Sie Ihre Mails ab oder surfen Sie im Web.
All diese Möglichkeiten stehen Ihnen auf Fingerdruck zur Verfügung – mit einem kompakten Telefon, das perfekt in der Hand liegt.
Sie möchten noch mehr mit dem Touch2 erleben? Dann laden Sie doch einfach Spiele und Anwendungen aus dem Windows Marketplace auf Ihr Handy, um es noch besser an Ihre Wünsche anzupassen.
Und damit Ihre Daten jederzeit sicher sind, können Sie direkt auf dem Microsoft MyPhone-Server ein Backup anlegen – ohne einen PC dafür zu benötigen.
Der HTC Touch2 bietet zahlreiche Verbesserungen bezüglich des TouchFLO, des User Interface (Wetterbericht, Shortcuts zu den beliebtesten Anwendungen...) und die Einführung von Google Maps für Mobiltelefone, YouTube und vieles mehr.
Touch2 - Technische Details :
Displaytaktiles 2.8"" TFT-LCD Display mit QVGA Auflösung Windows Mobile® 6.5
Professionaltaktile Front Panel Buttons für einfache Bedienbarkeit NetworkSchnelles Surfen und hohe Download-Geschwindigkeiten dank HSDPA
GPSintegrierte GPS Antenne
Fotoapparat3.2 Megapixel mit der Möglichkeit, Videos aufzunehmen
AnschlüsseWi-Fi (IEEE 802.11 b/g), Bluetooth 2.0, 3.5 mm Audioanschluss
Betriebssystem: HTC TouchFLO mit Windows Mobile 6.5 Professional
Verbindungsoptionen: GSM/Edge (850/900/1800/1900 MHz), WCDMA/HSDPA (900/2100 MHz), HSDPA (7,2 Mbps)
Gesprächszeiten: WCDMA bis zu 370 Minuten, GSM bis zu 440 Minuten
Standby-Zeiten: WCDMA bis zu 500 Stunden, GSM bis zu 370 Stunden
";2;False;0;;;HTC Touch 2;htc-touch-2;True;True;P-0016;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;299.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40650,9831712963;73;36;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000577-htc-touch-2.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"HTC HD2 ";"HTC HD2 in edlem schwarzen Design ";"
HTC HD2 in edlem schwarzen Design
  
Windows Mobile 6.5; 4,3 Zoll WVGA Touchscreen Display, 5 Megapixel-Kamera mit Auto-Fokus und LED Blitzlicht
 
Mit dem HTC HD2 präsentiert die HTC Corporation, weltweiter Marktführer bei Telefonen auf Basis von Windows Mobile und Android, das neue Flaggschiff seiner Windows Phone-Familie.
 
Der HTC HD2 ist das weltweit erste Windows Phone mit HTC Sense, einem mobilen Erlebnis, das den Anwender und seine natürlichen Handlungsstränge in den Mittelpunkt stellt.
Mächtige Leistungsreserven verspricht der mit 1 GHz getaktete Snapdragon-Prozessor von Qualcomm, der den HTC HD2 zur ultimativen Surf-, Multimedia- und Gaming-Maschine macht.
Erstes Windows Phone mit HTC Sense
HTC Sense basiert auf drei fundamentalen Prinzipien, die durch Zuhören und Beobachten, wie Menschen leben und kommunizieren, ermittelt wurden: Make it Mine, Stay Close und Discover the Unexpected.
Make it Mine
Der HD2 lässt sich maßgeschneidert an individuelle Anforderungen anpassen. Und dabei spielt das brillante Display seine gesamte Größe aus.
 
Animierte Hintergründe oder Wetterapplikationen (bei Regen fallen Regentropfen, bei bewölktem Himmel ziehen Wolkenschwaden über den Bildschirm etc.) vermitteln ein einzigartiges Erlebnis,
ohne dabei andere wichtige Anwendungen oder Inhalte zu stören.
Eine Vielzahl an Unterhaltungs- und Zusatzapplikationen aus dem Windows Marketplace for Mobile lädt zudem ein, den HD2 komplett an die eigenen Vorlieben anzupassen.
Stay Close
Egal über welche Art von Kommunikationskanal (Sprache, SMS, Email, Facebook etc.) die Verbindung mit Freunden, Verwandten oder Geschäftspartnern aufrecht gehalten werden soll,
der Personen-bezogene Kommunikationsansatz von HTC stellt zu jeder Kontaktperson die gesamte Konversationshistorie auf einen Fingerstreich zur Verfügung.

Discover the Unexpected
Auf Basis des mobilen Erlebnisses HTC Sense hält der HTC HD2 eine Vielzahl an Erweiterungen bereit, die den Umgang mit dem Smartphone-Giganten spürbar vereinfachen.
 
Der HD2 verfügt über diverse Sensoren, unter anderem einen Näherungssensor, der Fehleingaben während eines Telefonats verhindert.

Lieferumfang:
HTC Touch HD2, Akku, Ladekabel, USB-Kabel, kabelgebundenes Headset
";2;False;0;;;HTC HD2 Smartphone;htc-hd2;True;True;P-0011;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;3,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;599.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40650,9376967593;"73;2095";36;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000386-htc-hd2.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000387-htc-hd2.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000388-htc-hd2.jpg;1;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Sony Ericsson XPERIA X10 Mini Pro Smartphone;Sony Ericsson XPERIA X10 Mini Pro Smartphone (6,6 cm (2,6 Zoll) Display, QWERTZ-Tastatur, Android, WLAN, GPS, 5 Megapixel Kamera;"
Leistungsmerkmale des Sony Ericsson X10 Mini Pro Smartphone
Cleveres Zubehör
Rufen Sie Ihre Freunde an und lassen Sie Sich anrufen. Hören Sie Musik, halten Sie die Musik an und überspringen Sie einen Titel. Ganz ohne Ihr Handy. Sind Sie auf der Suche nach portablen Stereo-Lautsprechern? Die Sony Ericsson MS450 Lautsprecher (Optional) oder einem Hi-Fi-Headset mit Fernbedienung (z.B. Sony Ericsson MH810 - Optional)? Lassen Sie Ihr Handy in der Tasche und verwenden Sie Ihr Zubehör als Fernbedienung.
 
Timescape™ - Freunde treffen
Sony Ericsson Timescape™ ermöglicht die Anzeige der gesamten Kommunikation an einem Ort. Facebook™, Twitter™, SMS, Anrufe in Abwesenheit - alles in einer Anwendung zusammgefasst. Jede Menge geöffnete Anwendungen, um zu sehen, was gerade los ist? Die Zeiten sind endlich vorbei.
 
Mit der Kraft von QWERTZ
Sie tippen lieber auf einer Tastatur? Mit der kompletten QWERTZ-Tastatur können Sie Nachrichten noch einfacher schreiben.
 
Alles von überall
Die gesamte Kommunikation mit Ihren Freunden über das Telefonbuch. Alle Informationen zu Interpreten über den Music-Player. Einfach die Infinity-Taste berühren und schon werden alle Informationen angezeigt. Sofort.
 
Individuelle Freiheit
Ihre unverzichtbare Navigationsanwendung? Ihre Musik? Eine News-Site? Sie entscheiden, was wichtig für Sie ist. Wählen Sie die Symbole für die vier Ecken auf dem Startbildschirm selbst aus. Sie können die Anordnung jederzeit wieder ändern. In der Mitte des Bildschirms können Sie ein Widget einfügen. Gestalten Sie Ihren Bildschirm frei nach Ihren individuellen Bedürfnissen.
 
Android - Google - Apps
Das Xperia™ X10 Mini basiert auf der Android™-Plattform. Sie haben die Möglichkeit alle Google™-Anwendungen im vollen Umfang genießen zu können – Google Search™, Google Voice Search™, Google Talk™, Gmail™, YouTube™, Google™ Maps und dem Android Market™.
 
Selbst aussuchen - Android Market™
In Ausgehstimmung? In Aufbruchlaune? Oder im Ausruhmodus? Downloaden Sie jede beliebige Anwendung vom Android Market™ und passen Sie Ihr Xperia™ X10 Mini nach Ihren individuellen Vorlieben an.
 
HSPA – rasante Geschwindigkeit
Turbo-UMTS ermöglicht Ihnen breitbandähnliche Geschwindigkeiten auf dem Handy. Laden Sie große Dateien und E-Mail-Anhänge in wenigen Augenblicken herunter. Holen Sie sich Websites und Newsfeeds in Sekunden auf den Bildschirm.
 
Finden Sie Ihr Ziel - mit aGPS
Nie wieder verlaufen. Ihr Telefon verfügt über integriertes aGPS. Ortsgebundene Dienste helfen Ihnen, den Weg an Ihr Ziel zu finden. Oder fügen Sie Ihren Bildern mit der Geo-Tagging-Funktion Ortsangaben hinzu.
 
UKW-Radio
Musik liegt in der Luft - einfach einstellen und genießen. Ihr Handy verfügt über ein integriertes UKW-Radio.
 
Wi-Fi-Verbindung
Schnell und einfach in Verbindung bleiben. Unterwegs. In Cafés. Am Flughafen. Ihr Xperia™ X10 Mini unterstützt Wi-Fi.
";2;False;0;;;Sony Ericsson XPERIA X10 Mini Pro Smartphone;sony-ericsson-xperia-x10-mini-pro-smartphone;True;True;P-0027;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;159.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40650,9259606482;77;35;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000476-sony-ericsson-xperia-x10-mini-pro-smartphone.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000477-sony-ericsson-xperia-x10-mini-pro-smartphone.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000478-sony-ericsson-xperia-x10-mini-pro-smartphone.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Apple iPod touch 4G 64 GB ";"Der neue iPod touch. Jetzt mit FaceTime, Retina Display, HD-Video und Game Center. ";"
Der neue iPod touch. Jetzt mit FaceTime, Retina Display, HD-Video und Game Center.
 
Spaß, hoch entwickelt. Der neue iPod touch.
Tonnen von innovativen Funktionen gibt es jetzt auch auf dem iPod touch. Einfach damit er noch mehr Spaß macht. Teilen Sie schöne Momente mit Freunden via FaceTime. Nehmen Sie Videos in HD auf. Oder erleben Sie Spiele auf dem höchstauflösenden iPod Display, das es je gab. Der iPod touch hat so viel Technologie, dass Sie glatt vergessen, dass es ein iPod ist.
 
Sieht unglaublich aus. Ist aber wahr.

Mit seinem neuen Design ist der iPod touch der dünnste, leichteste und fantastischste iPod touch, den es je gab. Um das zu spüren, müssen Sie ihn nur in die Hand nehmen. Er ist gerade mal 7,2 mm dünn. Mit seiner Vorderseite aus Hightech-Glas und der Rückseite aus Edelstahl fühlt er sich einfach fantastisch an. Wenn Sie ihn einschalten, sind Sie sofort vom brillanten Retina Display fasziniert. Der iPod touch kombiniert großartiges Design und revolutionäre Technologie - von außen wie von innen.
 
Retina Display. Die Zukunft sieht gut aus.
Es gibt viele Gründe, den iPod touch immer wieder anzusehen. Beispielsweise das LCD-Display mit 960 x 640 Pixeln und Hintergrundbeleuchtung. Es hat eine Pixeldichte von 326 ppi und ist damit das höchstauflösende iPod Display, das es je gab. Die Apple Ingenieure haben dafür superkleine, kaum 78 Mikrometer breite Pixel entwickelt, die das menschliche Auge nicht mehr als einzelne Pixel wahrnehmen kann. Und obwohl Sie sie nicht sehen können, werden Sie den Unterschied bemerken. Der Text ist gestochen scharf und alles sieht leuchtend und lebendig aus.
 
Apple A4 Prozessor. Mehr Power für Sie.
Hinter - oder besser gesagt unter - dem ganzen Spaß, den Sie mit dem iPod touch haben, steckt der Apple A4 Chip. Die Apple Ingenieure haben den A4 Chip als leistungsstarken und energieeffizienten Mobilprozessor entworfen. Damit bewältigt der iPod touch komplexe Aufgaben wie Multitasking, Videoschnitt und FaceTime Anrufe. All das bei noch mehr Batterielaufzeit. Und mehr Spaß.
 
Gyrosensor + Beschleunigungssensor. Wirklich bewegend.
Der iPod touch hat jetzt ein paar neue Tricks drauf. Er hat einen integrierten 3-Achsen-Gyrosensor, der zusammen mit dem Beschleunigungssensor dafür sorgt, dass der iPod touch Aktionen wie Beschleunigung, 3D Bewegung und Drehrate erkennt. Im Klartext: Mehr Bewegungen, mehr Gesten und größere Präzision für noch mehr Spielspaß.
 
Zwei Kameras. Doppelt so viel Spaß.
Für Videoaufnahmen hat der iPod touch zwei integrierte Kameras. Mit der Rückkamera nimmt er fantastische HD 720p Videos auf. Und der hoch entwickelte rückwärtig belichtete Sensor sorgt selbst bei schwacher Beleuchtung für tolle Aufnahmen. Das integrierte Mikrofon nimmt dabei gleichzeitig Gespräche, Musik oder alles andere auf. Die Frontkamera des iPod touch ist perfekt für FaceTime Anrufe1 und um sich selbst aufzunehmen. Schon erstaunlich, wie viel Spaß in etwas so Kleines passt.
Multi-Touch. Alles unter Kontrolle Ihrer.
Wie macht der iPod touch eigentlich genau das, was Sie wollen, wenn Sie mit Ihren Fingern über das Display streichen? Genau genommen ist es eine Kettenreaktion. Das Multi-Touch Display hat einen Schutzfilm über der kapazitiven Sensorik, die Berührungen anhand elektrischer Felder erkennt. Diese Informationen werden an das Retina Display darunter übermittelt. So könen Sie alles mit den Fingern steuern, mit Cover Flow in Ihren Alben blättern, Fotos sehen und vergrößern, in eine Website zoomen und Spiele steuern.
 
FaceTime auf dem iPod touch. Sagen Sie nicht einfach Hallo. Sagen Sie es mit einem Lächeln.
Ein Lächeln sagt mehr als tausend SMS.
Bringen Sie LOL auf die nächste Stufe und sehen Sie Ihre Freunde wirklich lachen. Oder lassen Sie XOXO lebendig werden und schicken Sie einen Kuss um die halbe Welt. FaceTime auf dem iPod touch macht's möglich. FaceTime funktioniert sofort nach dem Auspacken - Sie geben einfach Ihre Apple ID und E-Mail Adresse ein. Oder erstellen einen neuen E-Mail Account extra für FaceTime. FaceTime ist supereinfach. Stellen Sie sich vor, Sie wollen über Wi-Fi mit Ihrer besten Freundin videotelefonieren. Dann tippen Sie auf die FaceTime App, finden sie dort und starten den Anruf. Auf ihrem iPod touch oder iPhone 4 erscheint dann eine Einladung, die sie annehmen kann. Sobald sie annimmt, wird FaceTime gestartet. Das alles funktioniert ganz nahtlos und sowohl im Hoch- als auch im Querformat. Sie werden im wahrsten Sinne des Wortes sehen, wie viel Spaß Sie haben können.
 
Videotelefonieren Sie mit Freunden per FaceTime oder spielen Sie gegen Freunde oder Fremde mit Game Center.
 
Zwei Kameras für Spaß von jeder Seite.
Der iPod touch hat zwei Kameras - eine vorne über dem Display und eine auf der Rückseite. Die Frontkamera ist für FaceTime optimiert. Sie hat genau das richtige Sichtfeld und die richtige Brennweite, um auf die Entfernung einer Armlänge das Gesicht zu fokussieren. So zeigt sie Sie immer im besten Licht. Was besonders praktisch ist, wenn Sie mit jemandem sprechen, der mehr als nur ein Freund ist.
Die Rückkamera. Teilen Sie Ihre Ansicht.
Wenn Ihre Mitbewohnerin es doch nicht mehr zum Konzert schafft, lassen Sie sie mit FaceTime doch wenigstens die Zugabe sehen. Wenn die Band auf die Bühne kommt und ihren Lieblingshit spielt, tippen Sie einfach auf die Taste. Und noch bevor der Sänger die erste Zeile singt, wechselt der iPod touch zur Rückkamera und überträgt einen mit Sicherheit legendären Auftritt. Tippen Sie noch einmal und der iPod touch wechselt zurück auf die Frontkamera und zu Ihnen. Einfach und schnell - macht einfach Spaß!
 
HD Videoaufnahme auf dem iPod touch. Nehmen Sie jeden Spaß mit. Und auf.
 
Integrierter Schnittplatz.
Sie müssen mit dem Bearbeiten Ihrer Videos nicht warten, bis Sie wieder am Computer sitzen. Einfache Schnittfunktionen sind direkt im iPod touch integriert, sodass Sie gleich damit loslegen können. Ziehen Sie einfach, um Start- und Endpunkt des Films festzulegen. Behalten Sie nur die Teile des Videos, die Ihnen besonders gefallen, und machen Sie daraus einen Film, den Sie und Ihre Freunde immer und immer wieder anschauen wollen.
 
Mit iMovie auf dem iPod touch erstellen Sie Minikinofilmhits mit ein paar Fingertipps.
Stellen Sie sich vor, Sie sind unterwegs und wollen eine Videopostkarte erstellen, mit allem, was Sie erlebt und gesehen haben. Machen Sie das einfach mit der iMovie App - Sie bekommen sie im App Store. Mit iMovie für den iPod touch können Sie Videoclips zusammenfügen und bearbeiten, ihnen mit dynamischen Themen und Übergängen noch eine Extraportion Wow geben, Musik und Fotos hinzufügen und den fertigen Film mit allen teilen.
 
Drehen Sie einen Film. Mit Ihnen in der Hauptrolle.
Wenn Sie das nächste Mal eine aufregende Wanderung gemacht haben, erzählen Sie Ihren Freunden nicht nur davon - zeigen Sie es ihnen. Neben der HD Kamera auf der Rückseite besitzt der iPod touch eine Frontkamera mit VGA-Qualität über dem Display. So sehen Sie sich selbst, während Sie Videos aufnehmen. Das ist perfekt, um sich selbst zu filmen, denn Sie brauchen nicht mehr zu hoffen, dass Sie im Bild sind, sondern sehen es gleich. Also machen Sie sich bereit für die Aufnahme.
 
Teilen Sie mit Freunden den Rest Ihres Lebens.
Haben Sie auch schon mal eine Mail geschrieben und dabei etwas Unbeschreibliches gesehen? Dann nehmen Sie die Kamera und nehmen Sie es auf. Anschließend können Sie Ihren HD Film direkt auf YouTube laden. Oder wählen Sie ein Video aus den Aufnahmen und verschicken es mit einer Mail. Sie können es auch mit einem Fingertipp auf Ihre Facebook Seite oder in Ihren Blog posten. Und alle mit dem iPod touch aufgenommenen Videos ganz leicht mit Ihrem Mac oder PC synchronisieren.
So haben alle ein gutes Bild von Ihnen.

Eine unglaubliche Aussicht. Ein toller Kuchen. Ihr Hund, wie er soooooo süß schaut. Wenn Sie einen Schnappschuss für Facebook machen wollen, können Sie eine der beiden Kameras des iPod touch verwenden. Tippen Sie einfach auf das Display, um die Belichtung anzupassen. Dann posten Sie das Bild auf Facebook und warten auf die Kommentare.
 
Game Center. Spielen Sie gegen Ihre besten Feinde
Game Center. Mögen die Spiele beginnen.
Mit der neuen Game Center App auf dem iPod touch können Sie Ihr Spiele-Netzwerk erweitern. Exponentiell. Zum Spielen brauchen Sie nur einen iPod touch oder ein iPhone mit iOS 4.1. Bei iOS 4.1 wird eine Game Center App auf dem Homescreen angezeigt. Tippen Sie einfach darauf, meldes sich mit Ihrer Apple ID an und schon kann´s losgehen. Sie können einen Spielernamen erstellen, der für Ihre Freunde und die Spieler-Community sichtbar ist. Fügen Sie mehrere E-Mail Adressen zur Game Center App hinzu, damit Freunde Sie einfacher finden können. Sie können die Spiele über die Links im Game Center laden und auch direkt aus der Game Center App starten. Und das Beste: Sobald Sie sich bei Game Center anmelden, bleiben Sie verbunden. Bis Sie dich wieder abmelden.
 
Beste Freunde. Bald beste Gegner.
Treten Sie gegen Ihre Freunde in einem Rennen an. Oder einem Match. Oder in einem Kampf. Wenn Sie bei der Game Center App angemeldet sind, können Sie jemanden mit einer Freundschaftsanfrage einladen und dafür den Spielernamen oder die E-Mail Adresse der Person verwenden. Ihre Freunde erscheinen in einer separaten Freundeliste in der Game Center App. Tippen Sie auf die Namen von Freunden und Sie sehen, welche Spiele sie gespielt haben. Sie können auch neue Freundschaftsanfragen ansehen und eigene hinzufügen.
Leaderbords und Erfolge. Damit jeder sieht, wo Sie stehen.
Sehen Sie sich auf den Ranglisten für jedes Spiel Ihre Platzierung unter Ihren Freunden und anderen Spielern an. Sie können auch Ihre Erfolge mit denen Ihrer Freunde vergleichen. Sehen Sie sich die Leaderboards und Erfolge in der Game Center App und jedem einzelnen Spiel an. Und dann lassen Sie es krachen.
 
Trefen Sie Ihre Gegner. Und treffen Sie sie hart.
Sie möchten eine Runde mit mehreren Freunden spielen? Mit Auto-Match werden Ihnen zuerst Ihre Freunde als Gegner vorgeschlagen, wenn diese auch nach einem Auto-Match suchen. Wenn nicht, wird Ihnen ein Freund in spe irgendwo auf dem Globus als Gegner vorgeschlagen. Oder laden Sie Ihre Freunde ein und lassen Sie Auto-Match alle für ein Spiel benötigten Spieler finden.
Musik. Lassen Sie Ihre Finger tanzen.
Cover Flow. Musik sieht so gut aus.
Auf dem iPod touch gibt's Musik nicht nur auf die Ohren. Mit Cover Flow ist sie auch was für Augen und Finger. Drehen Sie den iPod touch auf die Seite und blättern Sie durch Ihre Albumcover. Tippen Sie auf ein Cover, um es umzudrehen und die Songliste zu sehen. Noch ein Tipp und die Musik läuft.
 
Genius Wiedergabelisten. In jedem guten Song steckt eine noch bessere Wiedergabeliste.
Angenommen Sie hören einen Song auf einem iPod touch, der Ihnen gut gefällt, und möchten weitere Titel hören, die gut dazu passen. Genius findet weitere Songs auf Ihrem iPod touch und erstellt eine Genius Wiedergabeliste. Hören Sie sich die Liste sofort an, speichern Sie sie für später oder versuchen's noch einmal und sehen, was dabei herauskommt. Verlassen Sie sich auf Genius, wenn Sie einen Mix wollen, auf den Sie selbst nie gekommen wären. 
 
Genius Mixe. Nehmen Sie den DJ mit nach Hause.
Genius ist Ihr persönlicher DJ. Synchronisieren Sie Ihren iPod touch mit iTunes und Genius durchsucht Ihre Mediathek automatisch nach Songs, die gut zusammenpassen. Dann erstellt Genius mehrere Mixe. Diese Mixe sind wie Radiosender, auf denen nur Ihre Lieblingshits laufen. So finden Sie Songs wieder, die Sie lange nicht mehr gehört haben oder von denen Sie gar nicht mehr wussten, dass Sie sie haben.
 
Lassen Sie Ihre Finger tanzen. 
 
Shake to shuffle. So ein Zufall.
Die Dinge mal aufrütteln. Musikalisch natürlich. Wenn Sie das nächste Mal Musik hören, aktivieren Sie einfach die Schüttelfunktion. Wenn Sie den iPod touch dann kurz schütteln, springt er nach dem Zufallsprinzip zu einem anderen Song in Ihrer Sammlung. So entdecken Sie Ihre Musik immer wieder neu.
 
iTunes. Das ist Entertainment.
Packen Sie Songs und Musikvideos aus Ihrer iTunes Mediathek auf dem Computer auf den iPod touch. Oder kaufen und laden Sie neue Songs auf den iPod touch, wenn Sie sich über Wi-Fi mit iTunes verbinden. Wenn Sie dann den iPod touch das nächste Mal mit dem Computer verbinden, werden alle Songs, die Sie auf dem iPod touch gekauft haben, auf den Mac oder PC übertragen. Und mit iTunes Ping können Sie jetzt sehen, welche Musik Ihre Freunde hören, kaufen und empfehlen. Oder informieren Sie sich dort über Ihre Lieblingskünstler und was sie so hören.
 
Bluetooth. Entfesseln Sie Ihre Musik.
Die Unterstützung für das drahtlose Bluetooth ist im iPod touch schon drin. Das heißt, Sie können drahtlose Stereokopfhörer verwenden. Lassen Sie den iPod in Ihrer Tasche stecken oder auf dem Schreibtisch aufladen, während Sie weiter Musik hören.
 
Filme und Fernsehsendungen. So haben Sie überall eine Sehenswürdigkeit.
Ganz großes Kino. Auf einem kleinen Display.
Mit dem iPod touch ist jeden Tag und überall Kinotag. Nehmen Sie Videos für viele Stunden Unterhaltung mit und sehen Sie sie auf dem fantastischen 3,5 Zoll Retina Display an. Kaufen Sie im iTunes Store und wählen Sie aus tausenden Filmen, Fernsehsendungen und Video-Podcasts für Ihren iPod touch. Da ist für jeden etwas dabei - von Hollywood Blockbustern bis zu Independent Filmen. Ein paar Fingertipps und Sie haben Filme geladen und können sie ansehen. Sie mögen lieber Fernsehsendungen? Die gibt's auch. Sie können einzelne Folgen oder gleich eine ganze Staffel kaufen. Mit dem iPod touch haben Sie Ihre Videos immer dabei.
Sie haben alles unter Kontrolle.
Wenn Sie ein Video schauen, tippen Sie einfach auf das Display und schon haben Sie die Steuerung. Damit können Sie die Wiedergabe starten oder unterbrechen, zu einzelnen Kapiteln springen und die Lautstärke anpassen. Oder verwenden Sie die Lautstärketasten links am iPod touch. Wenn Sie zwischen Widescreen- und Vollbildanzeige wechseln wollen, reicht ein Doppeltipp auf das Display. Das ist wie die Fernbedienung des Fernsehers. Nur, dass Sie nicht darum kämpfen müssen.
 
iTunes. Für beste Unterhaltung.
Sie brauchen für den nächsten Flug oder die nächste Fahrt etwas Unterhaltung? Mit iTunes auf dem iPod touch und einer Wi-Fi Verbindung können Sie sofort Filme und Fernsehsendungen kaufen. Oder Sie kaufen sie auf Ihrem Mac oder PC und synchronisieren sie mit dem iPod touch. Nur das Popcorn ist nicht dabei.
 
 
Besuchen Sie Ihre Lieblingswebsites. Alles, was Sie dazu brauchen, ist ein iPod touch und Wi-Fi. 
 
Laden Sie die iBooks App kostenlos und Sie haben nicht nur einen großartigen E-Book-Reader, sondern auch einen tollen Ort, um Bücher zu kaufen. 
 
Und vieles mehr...
 
App Store
Laden Sie Apps direkt auf den iPod touch
 
iTunes
Erstellen Sie einen iTunes Store Account und kaufen Sie jederzeit via Wi-Fi ein.
 
iBooks
Laden Sie die iBooks App kostenlos und Sie haben nicht nur einen großartigen E-Book-Reader, sondern auch einen tollen Ort, um Bücher zu kaufen.
 
iMovie
Bearbeiten Sie Videos, fügen Sie Themen und Musik hinzu und teilen Sie Ihre Filme mit Anderen
 
Mail
Senden Sie Mails und sehen Sie sich Anhänge von Ihrem Google Mail, MobileMe oder einem anderen E-Mail Account an.
 
Safari Webbrowser
Besuchen Sie Ihre Lieblingswebsites. Alles, was Sie dazu brauchen, ist ein iPod touch und Wi-Fi.
 
Fotos
Nehmen Sie Ihre Fotos mit. Teilen Sie sie per E-Mail. Wählen Sie Ihr Lieblingsfoto als Hintergrundbild.
 
Homescreen
Ordnen Sie in iTunes Ihre Apps auf mehreren Homescreens an.
 
 
Sprachsteuerung
Steuern Sie die Musik auf dem iPod touch mit Sprachbefehlen
 
Karten
Finden Sie Restaurants, Konzerte und mehr und lassen Sie sich mit Karten zeigen, wie Sie hinkommen.
 
YouTube
Sehen Sie sich die neuesten Videohits und Ihre Lieblingsvideos an.
 
Nike + iPod
Erreichen Sie Ihre Trainingsziele mit integrierter Unterstützung für Nike + iPod
 
Sprachmemos
Nehmen Sie Notizen, Gedanken oder alles andere auf.
 
Bedienungshilfen
Der iPod touch kommt mit Bildschirmlesefunktion und weiteren Bedienungshilfen
 
Lieferumfang
iPod touch, Ohrhörer, USB 2.0 Kabel, Dock Adapter, Kurzanleitung
";2;False;0;;;"Apple iPod touch 4G 64 GB ";apple-ipod-touch-4g-64-gb;True;True;PD-01068;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;359.9900;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40637,4565162037;45;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000615-apple-ipod-touch-4g-32-gb.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000616-apple-ipod-touch-4g-32-gb.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000617-apple-ipod-touch-4g-32-gb.jpg;1;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Apple iPod touch 4G 8 GB ";"Der neue iPod touch. Jetzt mit FaceTime, Retina Display, HD-Video und Game Center. ";"
Der neue iPod touch. Jetzt mit FaceTime, Retina Display, HD-Video und Game Center.
 
Spaß, hoch entwickelt. Der neue iPod touch.
Tonnen von innovativen Funktionen gibt es jetzt auch auf dem iPod touch. Einfach damit er noch mehr Spaß macht. Teilen Sie schöne Momente mit Freunden via FaceTime. Nehmen Sie Videos in HD auf. Oder erleben Sie Spiele auf dem höchstauflösenden iPod Display, das es je gab. Der iPod touch hat so viel Technologie, dass Sie glatt vergessen, dass es ein iPod ist.
 
Sieht unglaublich aus. Ist aber wahr.

Mit seinem neuen Design ist der iPod touch der dünnste, leichteste und fantastischste iPod touch, den es je gab. Um das zu spüren, müssen Sie ihn nur in die Hand nehmen. Er ist gerade mal 7,2 mm dünn. Mit seiner Vorderseite aus Hightech-Glas und der Rückseite aus Edelstahl fühlt er sich einfach fantastisch an. Wenn Sie ihn einschalten, sind Sie sofort vom brillanten Retina Display fasziniert. Der iPod touch kombiniert großartiges Design und revolutionäre Technologie - von außen wie von innen.
 
Retina Display. Die Zukunft sieht gut aus.
Es gibt viele Gründe, den iPod touch immer wieder anzusehen. Beispielsweise das LCD-Display mit 960 x 640 Pixeln und Hintergrundbeleuchtung. Es hat eine Pixeldichte von 326 ppi und ist damit das höchstauflösende iPod Display, das es je gab. Die Apple Ingenieure haben dafür superkleine, kaum 78 Mikrometer breite Pixel entwickelt, die das menschliche Auge nicht mehr als einzelne Pixel wahrnehmen kann. Und obwohl Sie sie nicht sehen können, werden Sie den Unterschied bemerken. Der Text ist gestochen scharf und alles sieht leuchtend und lebendig aus.
 
Apple A4 Prozessor. Mehr Power für Sie.
Hinter - oder besser gesagt unter - dem ganzen Spaß, den Sie mit dem iPod touch haben, steckt der Apple A4 Chip. Die Apple Ingenieure haben den A4 Chip als leistungsstarken und energieeffizienten Mobilprozessor entworfen. Damit bewältigt der iPod touch komplexe Aufgaben wie Multitasking, Videoschnitt und FaceTime Anrufe. All das bei noch mehr Batterielaufzeit. Und mehr Spaß.
 
Gyrosensor + Beschleunigungssensor. Wirklich bewegend.
Der iPod touch hat jetzt ein paar neue Tricks drauf. Er hat einen integrierten 3-Achsen-Gyrosensor, der zusammen mit dem Beschleunigungssensor dafür sorgt, dass der iPod touch Aktionen wie Beschleunigung, 3D Bewegung und Drehrate erkennt. Im Klartext: Mehr Bewegungen, mehr Gesten und größere Präzision für noch mehr Spielspaß.
 
Zwei Kameras. Doppelt so viel Spaß.
Für Videoaufnahmen hat der iPod touch zwei integrierte Kameras. Mit der Rückkamera nimmt er fantastische HD 720p Videos auf. Und der hoch entwickelte rückwärtig belichtete Sensor sorgt selbst bei schwacher Beleuchtung für tolle Aufnahmen. Das integrierte Mikrofon nimmt dabei gleichzeitig Gespräche, Musik oder alles andere auf. Die Frontkamera des iPod touch ist perfekt für FaceTime Anrufe1 und um sich selbst aufzunehmen. Schon erstaunlich, wie viel Spaß in etwas so Kleines passt.
Multi-Touch. Alles unter Kontrolle Ihrer.
Wie macht der iPod touch eigentlich genau das, was Sie wollen, wenn Sie mit Ihren Fingern über das Display streichen? Genau genommen ist es eine Kettenreaktion. Das Multi-Touch Display hat einen Schutzfilm über der kapazitiven Sensorik, die Berührungen anhand elektrischer Felder erkennt. Diese Informationen werden an das Retina Display darunter übermittelt. So könen Sie alles mit den Fingern steuern, mit Cover Flow in Ihren Alben blättern, Fotos sehen und vergrößern, in eine Website zoomen und Spiele steuern.
 
FaceTime auf dem iPod touch. Sagen Sie nicht einfach Hallo. Sagen Sie es mit einem Lächeln.
Ein Lächeln sagt mehr als tausend SMS.
Bringen Sie LOL auf die nächste Stufe und sehen Sie Ihre Freunde wirklich lachen. Oder lassen Sie XOXO lebendig werden und schicken Sie einen Kuss um die halbe Welt. FaceTime auf dem iPod touch macht's möglich. FaceTime funktioniert sofort nach dem Auspacken - Sie geben einfach Ihre Apple ID und E-Mail Adresse ein. Oder erstellen einen neuen E-Mail Account extra für FaceTime. FaceTime ist supereinfach. Stellen Sie sich vor, Sie wollen über Wi-Fi mit Ihrer besten Freundin videotelefonieren. Dann tippen Sie auf die FaceTime App, finden sie dort und starten den Anruf. Auf ihrem iPod touch oder iPhone 4 erscheint dann eine Einladung, die sie annehmen kann. Sobald sie annimmt, wird FaceTime gestartet. Das alles funktioniert ganz nahtlos und sowohl im Hoch- als auch im Querformat. Sie werden im wahrsten Sinne des Wortes sehen, wie viel Spaß Sie haben können.
 
Videotelefonieren Sie mit Freunden per FaceTime oder spielen Sie gegen Freunde oder Fremde mit Game Center.
 
Zwei Kameras für Spaß von jeder Seite.
Der iPod touch hat zwei Kameras - eine vorne über dem Display und eine auf der Rückseite. Die Frontkamera ist für FaceTime optimiert. Sie hat genau das richtige Sichtfeld und die richtige Brennweite, um auf die Entfernung einer Armlänge das Gesicht zu fokussieren. So zeigt sie Sie immer im besten Licht. Was besonders praktisch ist, wenn Sie mit jemandem sprechen, der mehr als nur ein Freund ist.
Die Rückkamera. Teilen Sie Ihre Ansicht.
Wenn Ihre Mitbewohnerin es doch nicht mehr zum Konzert schafft, lassen Sie sie mit FaceTime doch wenigstens die Zugabe sehen. Wenn die Band auf die Bühne kommt und ihren Lieblingshit spielt, tippen Sie einfach auf die Taste. Und noch bevor der Sänger die erste Zeile singt, wechselt der iPod touch zur Rückkamera und überträgt einen mit Sicherheit legendären Auftritt. Tippen Sie noch einmal und der iPod touch wechselt zurück auf die Frontkamera und zu Ihnen. Einfach und schnell - macht einfach Spaß!
 
HD Videoaufnahme auf dem iPod touch. Nehmen Sie jeden Spaß mit. Und auf.
 
Integrierter Schnittplatz.
Sie müssen mit dem Bearbeiten Ihrer Videos nicht warten, bis Sie wieder am Computer sitzen. Einfache Schnittfunktionen sind direkt im iPod touch integriert, sodass Sie gleich damit loslegen können. Ziehen Sie einfach, um Start- und Endpunkt des Films festzulegen. Behalten Sie nur die Teile des Videos, die Ihnen besonders gefallen, und machen Sie daraus einen Film, den Sie und Ihre Freunde immer und immer wieder anschauen wollen.
 
Mit iMovie auf dem iPod touch erstellen Sie Minikinofilmhits mit ein paar Fingertipps.
Stellen Sie sich vor, Sie sind unterwegs und wollen eine Videopostkarte erstellen, mit allem, was Sie erlebt und gesehen haben. Machen Sie das einfach mit der iMovie App - Sie bekommen sie im App Store. Mit iMovie für den iPod touch können Sie Videoclips zusammenfügen und bearbeiten, ihnen mit dynamischen Themen und Übergängen noch eine Extraportion Wow geben, Musik und Fotos hinzufügen und den fertigen Film mit allen teilen.
 
Drehen Sie einen Film. Mit Ihnen in der Hauptrolle.
Wenn Sie das nächste Mal eine aufregende Wanderung gemacht haben, erzählen Sie Ihren Freunden nicht nur davon - zeigen Sie es ihnen. Neben der HD Kamera auf der Rückseite besitzt der iPod touch eine Frontkamera mit VGA-Qualität über dem Display. So sehen Sie sich selbst, während Sie Videos aufnehmen. Das ist perfekt, um sich selbst zu filmen, denn Sie brauchen nicht mehr zu hoffen, dass Sie im Bild sind, sondern sehen es gleich. Also machen Sie sich bereit für die Aufnahme.
 
Teilen Sie mit Freunden den Rest Ihres Lebens.
Haben Sie auch schon mal eine Mail geschrieben und dabei etwas Unbeschreibliches gesehen? Dann nehmen Sie die Kamera und nehmen Sie es auf. Anschließend können Sie Ihren HD Film direkt auf YouTube laden. Oder wählen Sie ein Video aus den Aufnahmen und verschicken es mit einer Mail. Sie können es auch mit einem Fingertipp auf Ihre Facebook Seite oder in Ihren Blog posten. Und alle mit dem iPod touch aufgenommenen Videos ganz leicht mit Ihrem Mac oder PC synchronisieren.
So haben alle ein gutes Bild von Ihnen.

Eine unglaubliche Aussicht. Ein toller Kuchen. Ihr Hund, wie er soooooo süß schaut. Wenn Sie einen Schnappschuss für Facebook machen wollen, können Sie eine der beiden Kameras des iPod touch verwenden. Tippen Sie einfach auf das Display, um die Belichtung anzupassen. Dann posten Sie das Bild auf Facebook und warten auf die Kommentare.
 
Game Center. Spielen Sie gegen Ihre besten Feinde
Game Center. Mögen die Spiele beginnen.
Mit der neuen Game Center App auf dem iPod touch können Sie Ihr Spiele-Netzwerk erweitern. Exponentiell. Zum Spielen brauchen Sie nur einen iPod touch oder ein iPhone mit iOS 4.1. Bei iOS 4.1 wird eine Game Center App auf dem Homescreen angezeigt. Tippen Sie einfach darauf, meldes sich mit Ihrer Apple ID an und schon kann´s losgehen. Sie können einen Spielernamen erstellen, der für Ihre Freunde und die Spieler-Community sichtbar ist. Fügen Sie mehrere E-Mail Adressen zur Game Center App hinzu, damit Freunde Sie einfacher finden können. Sie können die Spiele über die Links im Game Center laden und auch direkt aus der Game Center App starten. Und das Beste: Sobald Sie sich bei Game Center anmelden, bleiben Sie verbunden. Bis Sie dich wieder abmelden.
 
Beste Freunde. Bald beste Gegner.
Treten Sie gegen Ihre Freunde in einem Rennen an. Oder einem Match. Oder in einem Kampf. Wenn Sie bei der Game Center App angemeldet sind, können Sie jemanden mit einer Freundschaftsanfrage einladen und dafür den Spielernamen oder die E-Mail Adresse der Person verwenden. Ihre Freunde erscheinen in einer separaten Freundeliste in der Game Center App. Tippen Sie auf die Namen von Freunden und Sie sehen, welche Spiele sie gespielt haben. Sie können auch neue Freundschaftsanfragen ansehen und eigene hinzufügen.
Leaderbords und Erfolge. Damit jeder sieht, wo Sie stehen.
Sehen Sie sich auf den Ranglisten für jedes Spiel Ihre Platzierung unter Ihren Freunden und anderen Spielern an. Sie können auch Ihre Erfolge mit denen Ihrer Freunde vergleichen. Sehen Sie sich die Leaderboards und Erfolge in der Game Center App und jedem einzelnen Spiel an. Und dann lassen Sie es krachen.
 
Trefen Sie Ihre Gegner. Und treffen Sie sie hart.
Sie möchten eine Runde mit mehreren Freunden spielen? Mit Auto-Match werden Ihnen zuerst Ihre Freunde als Gegner vorgeschlagen, wenn diese auch nach einem Auto-Match suchen. Wenn nicht, wird Ihnen ein Freund in spe irgendwo auf dem Globus als Gegner vorgeschlagen. Oder laden Sie Ihre Freunde ein und lassen Sie Auto-Match alle für ein Spiel benötigten Spieler finden.
Musik. Lassen Sie Ihre Finger tanzen.
Cover Flow. Musik sieht so gut aus.
Auf dem iPod touch gibt's Musik nicht nur auf die Ohren. Mit Cover Flow ist sie auch was für Augen und Finger. Drehen Sie den iPod touch auf die Seite und blättern Sie durch Ihre Albumcover. Tippen Sie auf ein Cover, um es umzudrehen und die Songliste zu sehen. Noch ein Tipp und die Musik läuft.
 
Genius Wiedergabelisten. In jedem guten Song steckt eine noch bessere Wiedergabeliste.
Angenommen Sie hören einen Song auf einem iPod touch, der Ihnen gut gefällt, und möchten weitere Titel hören, die gut dazu passen. Genius findet weitere Songs auf Ihrem iPod touch und erstellt eine Genius Wiedergabeliste. Hören Sie sich die Liste sofort an, speichern Sie sie für später oder versuchen's noch einmal und sehen, was dabei herauskommt. Verlassen Sie sich auf Genius, wenn Sie einen Mix wollen, auf den Sie selbst nie gekommen wären. 
 
Genius Mixe. Nehmen Sie den DJ mit nach Hause.
Genius ist Ihr persönlicher DJ. Synchronisieren Sie Ihren iPod touch mit iTunes und Genius durchsucht Ihre Mediathek automatisch nach Songs, die gut zusammenpassen. Dann erstellt Genius mehrere Mixe. Diese Mixe sind wie Radiosender, auf denen nur Ihre Lieblingshits laufen. So finden Sie Songs wieder, die Sie lange nicht mehr gehört haben oder von denen Sie gar nicht mehr wussten, dass Sie sie haben.
 
Lassen Sie Ihre Finger tanzen. 
 
Shake to shuffle. So ein Zufall.
Die Dinge mal aufrütteln. Musikalisch natürlich. Wenn Sie das nächste Mal Musik hören, aktivieren Sie einfach die Schüttelfunktion. Wenn Sie den iPod touch dann kurz schütteln, springt er nach dem Zufallsprinzip zu einem anderen Song in Ihrer Sammlung. So entdecken Sie Ihre Musik immer wieder neu.
 
iTunes. Das ist Entertainment.
Packen Sie Songs und Musikvideos aus Ihrer iTunes Mediathek auf dem Computer auf den iPod touch. Oder kaufen und laden Sie neue Songs auf den iPod touch, wenn Sie sich über Wi-Fi mit iTunes verbinden. Wenn Sie dann den iPod touch das nächste Mal mit dem Computer verbinden, werden alle Songs, die Sie auf dem iPod touch gekauft haben, auf den Mac oder PC übertragen. Und mit iTunes Ping können Sie jetzt sehen, welche Musik Ihre Freunde hören, kaufen und empfehlen. Oder informieren Sie sich dort über Ihre Lieblingskünstler und was sie so hören.
 
Bluetooth. Entfesseln Sie Ihre Musik.
Die Unterstützung für das drahtlose Bluetooth ist im iPod touch schon drin. Das heißt, Sie können drahtlose Stereokopfhörer verwenden. Lassen Sie den iPod in Ihrer Tasche stecken oder auf dem Schreibtisch aufladen, während Sie weiter Musik hören.
 
Filme und Fernsehsendungen. So haben Sie überall eine Sehenswürdigkeit.
Ganz großes Kino. Auf einem kleinen Display.
Mit dem iPod touch ist jeden Tag und überall Kinotag. Nehmen Sie Videos für viele Stunden Unterhaltung mit und sehen Sie sie auf dem fantastischen 3,5 Zoll Retina Display an. Kaufen Sie im iTunes Store und wählen Sie aus tausenden Filmen, Fernsehsendungen und Video-Podcasts für Ihren iPod touch. Da ist für jeden etwas dabei - von Hollywood Blockbustern bis zu Independent Filmen. Ein paar Fingertipps und Sie haben Filme geladen und können sie ansehen. Sie mögen lieber Fernsehsendungen? Die gibt's auch. Sie können einzelne Folgen oder gleich eine ganze Staffel kaufen. Mit dem iPod touch haben Sie Ihre Videos immer dabei.
Sie haben alles unter Kontrolle.
Wenn Sie ein Video schauen, tippen Sie einfach auf das Display und schon haben Sie die Steuerung. Damit können Sie die Wiedergabe starten oder unterbrechen, zu einzelnen Kapiteln springen und die Lautstärke anpassen. Oder verwenden Sie die Lautstärketasten links am iPod touch. Wenn Sie zwischen Widescreen- und Vollbildanzeige wechseln wollen, reicht ein Doppeltipp auf das Display. Das ist wie die Fernbedienung des Fernsehers. Nur, dass Sie nicht darum kämpfen müssen.
 
iTunes. Für beste Unterhaltung.
Sie brauchen für den nächsten Flug oder die nächste Fahrt etwas Unterhaltung? Mit iTunes auf dem iPod touch und einer Wi-Fi Verbindung können Sie sofort Filme und Fernsehsendungen kaufen. Oder Sie kaufen sie auf Ihrem Mac oder PC und synchronisieren sie mit dem iPod touch. Nur das Popcorn ist nicht dabei.
 
 
Besuchen Sie Ihre Lieblingswebsites. Alles, was Sie dazu brauchen, ist ein iPod touch und Wi-Fi. 
 
Laden Sie die iBooks App kostenlos und Sie haben nicht nur einen großartigen E-Book-Reader, sondern auch einen tollen Ort, um Bücher zu kaufen. 
 
Und vieles mehr...
 
App Store
Laden Sie Apps direkt auf den iPod touch
 
iTunes
Erstellen Sie einen iTunes Store Account und kaufen Sie jederzeit via Wi-Fi ein.
 
iBooks
Laden Sie die iBooks App kostenlos und Sie haben nicht nur einen großartigen E-Book-Reader, sondern auch einen tollen Ort, um Bücher zu kaufen.
 
iMovie
Bearbeiten Sie Videos, fügen Sie Themen und Musik hinzu und teilen Sie Ihre Filme mit Anderen
 
Mail
Senden Sie Mails und sehen Sie sich Anhänge von Ihrem Google Mail, MobileMe oder einem anderen E-Mail Account an.
 
Safari Webbrowser
Besuchen Sie Ihre Lieblingswebsites. Alles, was Sie dazu brauchen, ist ein iPod touch und Wi-Fi.
 
Fotos
Nehmen Sie Ihre Fotos mit. Teilen Sie sie per E-Mail. Wählen Sie Ihr Lieblingsfoto als Hintergrundbild.
 
Homescreen
Ordnen Sie in iTunes Ihre Apps auf mehreren Homescreens an.
 
 
Sprachsteuerung
Steuern Sie die Musik auf dem iPod touch mit Sprachbefehlen
 
Karten
Finden Sie Restaurants, Konzerte und mehr und lassen Sie sich mit Karten zeigen, wie Sie hinkommen.
 
YouTube
Sehen Sie sich die neuesten Videohits und Ihre Lieblingsvideos an.
 
Nike + iPod
Erreichen Sie Ihre Trainingsziele mit integrierter Unterstützung für Nike + iPod
 
Sprachmemos
Nehmen Sie Notizen, Gedanken oder alles andere auf.
 
Bedienungshilfen
Der iPod touch kommt mit Bildschirmlesefunktion und weiteren Bedienungshilfen
 
Lieferumfang
iPod touch, Ohrhörer, USB 2.0 Kabel, Dock Adapter, Kurzanleitung
";2;False;0;;;"Apple iPod touch 4G 8 GB ";apple-ipod-touch-4g-8-gb;True;True;PD-01067;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;209.9900;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40637,4560300926;45;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000615-apple-ipod-touch-4g-32-gb.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000616-apple-ipod-touch-4g-32-gb.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000617-apple-ipod-touch-4g-32-gb.jpg;1;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Apple iPod touch 4G 32 GB ";"Der neue iPod touch. Jetzt mit FaceTime, Retina Display, HD-Video und Game Center. ";"
Der neue iPod touch. Jetzt mit FaceTime, Retina Display, HD-Video und Game Center.
 
Spaß, hoch entwickelt. Der neue iPod touch.
Tonnen von innovativen Funktionen gibt es jetzt auch auf dem iPod touch. Einfach damit er noch mehr Spaß macht. Teilen Sie schöne Momente mit Freunden via FaceTime. Nehmen Sie Videos in HD auf. Oder erleben Sie Spiele auf dem höchstauflösenden iPod Display, das es je gab. Der iPod touch hat so viel Technologie, dass Sie glatt vergessen, dass es ein iPod ist.
 
Sieht unglaublich aus. Ist aber wahr.

Mit seinem neuen Design ist der iPod touch der dünnste, leichteste und fantastischste iPod touch, den es je gab. Um das zu spüren, müssen Sie ihn nur in die Hand nehmen. Er ist gerade mal 7,2 mm dünn. Mit seiner Vorderseite aus Hightech-Glas und der Rückseite aus Edelstahl fühlt er sich einfach fantastisch an. Wenn Sie ihn einschalten, sind Sie sofort vom brillanten Retina Display fasziniert. Der iPod touch kombiniert großartiges Design und revolutionäre Technologie - von außen wie von innen.
 
Retina Display. Die Zukunft sieht gut aus.
Es gibt viele Gründe, den iPod touch immer wieder anzusehen. Beispielsweise das LCD-Display mit 960 x 640 Pixeln und Hintergrundbeleuchtung. Es hat eine Pixeldichte von 326 ppi und ist damit das höchstauflösende iPod Display, das es je gab. Die Apple Ingenieure haben dafür superkleine, kaum 78 Mikrometer breite Pixel entwickelt, die das menschliche Auge nicht mehr als einzelne Pixel wahrnehmen kann. Und obwohl Sie sie nicht sehen können, werden Sie den Unterschied bemerken. Der Text ist gestochen scharf und alles sieht leuchtend und lebendig aus.
 
Apple A4 Prozessor. Mehr Power für Sie.
Hinter - oder besser gesagt unter - dem ganzen Spaß, den Sie mit dem iPod touch haben, steckt der Apple A4 Chip. Die Apple Ingenieure haben den A4 Chip als leistungsstarken und energieeffizienten Mobilprozessor entworfen. Damit bewältigt der iPod touch komplexe Aufgaben wie Multitasking, Videoschnitt und FaceTime Anrufe. All das bei noch mehr Batterielaufzeit. Und mehr Spaß.
 
Gyrosensor + Beschleunigungssensor. Wirklich bewegend.
Der iPod touch hat jetzt ein paar neue Tricks drauf. Er hat einen integrierten 3-Achsen-Gyrosensor, der zusammen mit dem Beschleunigungssensor dafür sorgt, dass der iPod touch Aktionen wie Beschleunigung, 3D Bewegung und Drehrate erkennt. Im Klartext: Mehr Bewegungen, mehr Gesten und größere Präzision für noch mehr Spielspaß.
 
Zwei Kameras. Doppelt so viel Spaß.
Für Videoaufnahmen hat der iPod touch zwei integrierte Kameras. Mit der Rückkamera nimmt er fantastische HD 720p Videos auf. Und der hoch entwickelte rückwärtig belichtete Sensor sorgt selbst bei schwacher Beleuchtung für tolle Aufnahmen. Das integrierte Mikrofon nimmt dabei gleichzeitig Gespräche, Musik oder alles andere auf. Die Frontkamera des iPod touch ist perfekt für FaceTime Anrufe1 und um sich selbst aufzunehmen. Schon erstaunlich, wie viel Spaß in etwas so Kleines passt.
Multi-Touch. Alles unter Kontrolle Ihrer.
Wie macht der iPod touch eigentlich genau das, was Sie wollen, wenn Sie mit Ihren Fingern über das Display streichen? Genau genommen ist es eine Kettenreaktion. Das Multi-Touch Display hat einen Schutzfilm über der kapazitiven Sensorik, die Berührungen anhand elektrischer Felder erkennt. Diese Informationen werden an das Retina Display darunter übermittelt. So könen Sie alles mit den Fingern steuern, mit Cover Flow in Ihren Alben blättern, Fotos sehen und vergrößern, in eine Website zoomen und Spiele steuern.
 
FaceTime auf dem iPod touch. Sagen Sie nicht einfach Hallo. Sagen Sie es mit einem Lächeln.
Ein Lächeln sagt mehr als tausend SMS.
Bringen Sie LOL auf die nächste Stufe und sehen Sie Ihre Freunde wirklich lachen. Oder lassen Sie XOXO lebendig werden und schicken Sie einen Kuss um die halbe Welt. FaceTime auf dem iPod touch macht's möglich. FaceTime funktioniert sofort nach dem Auspacken - Sie geben einfach Ihre Apple ID und E-Mail Adresse ein. Oder erstellen einen neuen E-Mail Account extra für FaceTime. FaceTime ist supereinfach. Stellen Sie sich vor, Sie wollen über Wi-Fi mit Ihrer besten Freundin videotelefonieren. Dann tippen Sie auf die FaceTime App, finden sie dort und starten den Anruf. Auf ihrem iPod touch oder iPhone 4 erscheint dann eine Einladung, die sie annehmen kann. Sobald sie annimmt, wird FaceTime gestartet. Das alles funktioniert ganz nahtlos und sowohl im Hoch- als auch im Querformat. Sie werden im wahrsten Sinne des Wortes sehen, wie viel Spaß Sie haben können.
 
Videotelefonieren Sie mit Freunden per FaceTime oder spielen Sie gegen Freunde oder Fremde mit Game Center.
 
Zwei Kameras für Spaß von jeder Seite.
Der iPod touch hat zwei Kameras - eine vorne über dem Display und eine auf der Rückseite. Die Frontkamera ist für FaceTime optimiert. Sie hat genau das richtige Sichtfeld und die richtige Brennweite, um auf die Entfernung einer Armlänge das Gesicht zu fokussieren. So zeigt sie Sie immer im besten Licht. Was besonders praktisch ist, wenn Sie mit jemandem sprechen, der mehr als nur ein Freund ist.
Die Rückkamera. Teilen Sie Ihre Ansicht.
Wenn Ihre Mitbewohnerin es doch nicht mehr zum Konzert schafft, lassen Sie sie mit FaceTime doch wenigstens die Zugabe sehen. Wenn die Band auf die Bühne kommt und ihren Lieblingshit spielt, tippen Sie einfach auf die Taste. Und noch bevor der Sänger die erste Zeile singt, wechselt der iPod touch zur Rückkamera und überträgt einen mit Sicherheit legendären Auftritt. Tippen Sie noch einmal und der iPod touch wechselt zurück auf die Frontkamera und zu Ihnen. Einfach und schnell - macht einfach Spaß!
 
HD Videoaufnahme auf dem iPod touch. Nehmen Sie jeden Spaß mit. Und auf.
 
Integrierter Schnittplatz.
Sie müssen mit dem Bearbeiten Ihrer Videos nicht warten, bis Sie wieder am Computer sitzen. Einfache Schnittfunktionen sind direkt im iPod touch integriert, sodass Sie gleich damit loslegen können. Ziehen Sie einfach, um Start- und Endpunkt des Films festzulegen. Behalten Sie nur die Teile des Videos, die Ihnen besonders gefallen, und machen Sie daraus einen Film, den Sie und Ihre Freunde immer und immer wieder anschauen wollen.
 
Mit iMovie auf dem iPod touch erstellen Sie Minikinofilmhits mit ein paar Fingertipps.
Stellen Sie sich vor, Sie sind unterwegs und wollen eine Videopostkarte erstellen, mit allem, was Sie erlebt und gesehen haben. Machen Sie das einfach mit der iMovie App - Sie bekommen sie im App Store. Mit iMovie für den iPod touch können Sie Videoclips zusammenfügen und bearbeiten, ihnen mit dynamischen Themen und Übergängen noch eine Extraportion Wow geben, Musik und Fotos hinzufügen und den fertigen Film mit allen teilen.
 
Drehen Sie einen Film. Mit Ihnen in der Hauptrolle.
Wenn Sie das nächste Mal eine aufregende Wanderung gemacht haben, erzählen Sie Ihren Freunden nicht nur davon - zeigen Sie es ihnen. Neben der HD Kamera auf der Rückseite besitzt der iPod touch eine Frontkamera mit VGA-Qualität über dem Display. So sehen Sie sich selbst, während Sie Videos aufnehmen. Das ist perfekt, um sich selbst zu filmen, denn Sie brauchen nicht mehr zu hoffen, dass Sie im Bild sind, sondern sehen es gleich. Also machen Sie sich bereit für die Aufnahme.
 
Teilen Sie mit Freunden den Rest Ihres Lebens.
Haben Sie auch schon mal eine Mail geschrieben und dabei etwas Unbeschreibliches gesehen? Dann nehmen Sie die Kamera und nehmen Sie es auf. Anschließend können Sie Ihren HD Film direkt auf YouTube laden. Oder wählen Sie ein Video aus den Aufnahmen und verschicken es mit einer Mail. Sie können es auch mit einem Fingertipp auf Ihre Facebook Seite oder in Ihren Blog posten. Und alle mit dem iPod touch aufgenommenen Videos ganz leicht mit Ihrem Mac oder PC synchronisieren.
So haben alle ein gutes Bild von Ihnen.

Eine unglaubliche Aussicht. Ein toller Kuchen. Ihr Hund, wie er soooooo süß schaut. Wenn Sie einen Schnappschuss für Facebook machen wollen, können Sie eine der beiden Kameras des iPod touch verwenden. Tippen Sie einfach auf das Display, um die Belichtung anzupassen. Dann posten Sie das Bild auf Facebook und warten auf die Kommentare.
 
Game Center. Spielen Sie gegen Ihre besten Feinde
Game Center. Mögen die Spiele beginnen.
Mit der neuen Game Center App auf dem iPod touch können Sie Ihr Spiele-Netzwerk erweitern. Exponentiell. Zum Spielen brauchen Sie nur einen iPod touch oder ein iPhone mit iOS 4.1. Bei iOS 4.1 wird eine Game Center App auf dem Homescreen angezeigt. Tippen Sie einfach darauf, meldes sich mit Ihrer Apple ID an und schon kann´s losgehen. Sie können einen Spielernamen erstellen, der für Ihre Freunde und die Spieler-Community sichtbar ist. Fügen Sie mehrere E-Mail Adressen zur Game Center App hinzu, damit Freunde Sie einfacher finden können. Sie können die Spiele über die Links im Game Center laden und auch direkt aus der Game Center App starten. Und das Beste: Sobald Sie sich bei Game Center anmelden, bleiben Sie verbunden. Bis Sie dich wieder abmelden.
 
Beste Freunde. Bald beste Gegner.
Treten Sie gegen Ihre Freunde in einem Rennen an. Oder einem Match. Oder in einem Kampf. Wenn Sie bei der Game Center App angemeldet sind, können Sie jemanden mit einer Freundschaftsanfrage einladen und dafür den Spielernamen oder die E-Mail Adresse der Person verwenden. Ihre Freunde erscheinen in einer separaten Freundeliste in der Game Center App. Tippen Sie auf die Namen von Freunden und Sie sehen, welche Spiele sie gespielt haben. Sie können auch neue Freundschaftsanfragen ansehen und eigene hinzufügen.
Leaderbords und Erfolge. Damit jeder sieht, wo Sie stehen.
Sehen Sie sich auf den Ranglisten für jedes Spiel Ihre Platzierung unter Ihren Freunden und anderen Spielern an. Sie können auch Ihre Erfolge mit denen Ihrer Freunde vergleichen. Sehen Sie sich die Leaderboards und Erfolge in der Game Center App und jedem einzelnen Spiel an. Und dann lassen Sie es krachen.
 
Trefen Sie Ihre Gegner. Und treffen Sie sie hart.
Sie möchten eine Runde mit mehreren Freunden spielen? Mit Auto-Match werden Ihnen zuerst Ihre Freunde als Gegner vorgeschlagen, wenn diese auch nach einem Auto-Match suchen. Wenn nicht, wird Ihnen ein Freund in spe irgendwo auf dem Globus als Gegner vorgeschlagen. Oder laden Sie Ihre Freunde ein und lassen Sie Auto-Match alle für ein Spiel benötigten Spieler finden.
Musik. Lassen Sie Ihre Finger tanzen.
Cover Flow. Musik sieht so gut aus.
Auf dem iPod touch gibt's Musik nicht nur auf die Ohren. Mit Cover Flow ist sie auch was für Augen und Finger. Drehen Sie den iPod touch auf die Seite und blättern Sie durch Ihre Albumcover. Tippen Sie auf ein Cover, um es umzudrehen und die Songliste zu sehen. Noch ein Tipp und die Musik läuft.
 
Genius Wiedergabelisten. In jedem guten Song steckt eine noch bessere Wiedergabeliste.
Angenommen Sie hören einen Song auf einem iPod touch, der Ihnen gut gefällt, und möchten weitere Titel hören, die gut dazu passen. Genius findet weitere Songs auf Ihrem iPod touch und erstellt eine Genius Wiedergabeliste. Hören Sie sich die Liste sofort an, speichern Sie sie für später oder versuchen's noch einmal und sehen, was dabei herauskommt. Verlassen Sie sich auf Genius, wenn Sie einen Mix wollen, auf den Sie selbst nie gekommen wären. 
 
Genius Mixe. Nehmen Sie den DJ mit nach Hause.
Genius ist Ihr persönlicher DJ. Synchronisieren Sie Ihren iPod touch mit iTunes und Genius durchsucht Ihre Mediathek automatisch nach Songs, die gut zusammenpassen. Dann erstellt Genius mehrere Mixe. Diese Mixe sind wie Radiosender, auf denen nur Ihre Lieblingshits laufen. So finden Sie Songs wieder, die Sie lange nicht mehr gehört haben oder von denen Sie gar nicht mehr wussten, dass Sie sie haben.
 
Lassen Sie Ihre Finger tanzen. 
 
Shake to shuffle. So ein Zufall.
Die Dinge mal aufrütteln. Musikalisch natürlich. Wenn Sie das nächste Mal Musik hören, aktivieren Sie einfach die Schüttelfunktion. Wenn Sie den iPod touch dann kurz schütteln, springt er nach dem Zufallsprinzip zu einem anderen Song in Ihrer Sammlung. So entdecken Sie Ihre Musik immer wieder neu.
 
iTunes. Das ist Entertainment.
Packen Sie Songs und Musikvideos aus Ihrer iTunes Mediathek auf dem Computer auf den iPod touch. Oder kaufen und laden Sie neue Songs auf den iPod touch, wenn Sie sich über Wi-Fi mit iTunes verbinden. Wenn Sie dann den iPod touch das nächste Mal mit dem Computer verbinden, werden alle Songs, die Sie auf dem iPod touch gekauft haben, auf den Mac oder PC übertragen. Und mit iTunes Ping können Sie jetzt sehen, welche Musik Ihre Freunde hören, kaufen und empfehlen. Oder informieren Sie sich dort über Ihre Lieblingskünstler und was sie so hören.
 
Bluetooth. Entfesseln Sie Ihre Musik.
Die Unterstützung für das drahtlose Bluetooth ist im iPod touch schon drin. Das heißt, Sie können drahtlose Stereokopfhörer verwenden. Lassen Sie den iPod in Ihrer Tasche stecken oder auf dem Schreibtisch aufladen, während Sie weiter Musik hören.
 
Filme und Fernsehsendungen. So haben Sie überall eine Sehenswürdigkeit.
Ganz großes Kino. Auf einem kleinen Display.
Mit dem iPod touch ist jeden Tag und überall Kinotag. Nehmen Sie Videos für viele Stunden Unterhaltung mit und sehen Sie sie auf dem fantastischen 3,5 Zoll Retina Display an. Kaufen Sie im iTunes Store und wählen Sie aus tausenden Filmen, Fernsehsendungen und Video-Podcasts für Ihren iPod touch. Da ist für jeden etwas dabei - von Hollywood Blockbustern bis zu Independent Filmen. Ein paar Fingertipps und Sie haben Filme geladen und können sie ansehen. Sie mögen lieber Fernsehsendungen? Die gibt's auch. Sie können einzelne Folgen oder gleich eine ganze Staffel kaufen. Mit dem iPod touch haben Sie Ihre Videos immer dabei.
Sie haben alles unter Kontrolle.
Wenn Sie ein Video schauen, tippen Sie einfach auf das Display und schon haben Sie die Steuerung. Damit können Sie die Wiedergabe starten oder unterbrechen, zu einzelnen Kapiteln springen und die Lautstärke anpassen. Oder verwenden Sie die Lautstärketasten links am iPod touch. Wenn Sie zwischen Widescreen- und Vollbildanzeige wechseln wollen, reicht ein Doppeltipp auf das Display. Das ist wie die Fernbedienung des Fernsehers. Nur, dass Sie nicht darum kämpfen müssen.
 
iTunes. Für beste Unterhaltung.
Sie brauchen für den nächsten Flug oder die nächste Fahrt etwas Unterhaltung? Mit iTunes auf dem iPod touch und einer Wi-Fi Verbindung können Sie sofort Filme und Fernsehsendungen kaufen. Oder Sie kaufen sie auf Ihrem Mac oder PC und synchronisieren sie mit dem iPod touch. Nur das Popcorn ist nicht dabei.
 
 
Besuchen Sie Ihre Lieblingswebsites. Alles, was Sie dazu brauchen, ist ein iPod touch und Wi-Fi. 
 
Laden Sie die iBooks App kostenlos und Sie haben nicht nur einen großartigen E-Book-Reader, sondern auch einen tollen Ort, um Bücher zu kaufen. 
 
Und vieles mehr...
 
App Store
Laden Sie Apps direkt auf den iPod touch
 
iTunes
Erstellen Sie einen iTunes Store Account und kaufen Sie jederzeit via Wi-Fi ein.
 
iBooks
Laden Sie die iBooks App kostenlos und Sie haben nicht nur einen großartigen E-Book-Reader, sondern auch einen tollen Ort, um Bücher zu kaufen.
 
iMovie
Bearbeiten Sie Videos, fügen Sie Themen und Musik hinzu und teilen Sie Ihre Filme mit Anderen
 
Mail
Senden Sie Mails und sehen Sie sich Anhänge von Ihrem Google Mail, MobileMe oder einem anderen E-Mail Account an.
 
Safari Webbrowser
Besuchen Sie Ihre Lieblingswebsites. Alles, was Sie dazu brauchen, ist ein iPod touch und Wi-Fi.
 
Fotos
Nehmen Sie Ihre Fotos mit. Teilen Sie sie per E-Mail. Wählen Sie Ihr Lieblingsfoto als Hintergrundbild.
 
Homescreen
Ordnen Sie in iTunes Ihre Apps auf mehreren Homescreens an.
 
 
Sprachsteuerung
Steuern Sie die Musik auf dem iPod touch mit Sprachbefehlen
 
Karten
Finden Sie Restaurants, Konzerte und mehr und lassen Sie sich mit Karten zeigen, wie Sie hinkommen.
 
YouTube
Sehen Sie sich die neuesten Videohits und Ihre Lieblingsvideos an.
 
Nike + iPod
Erreichen Sie Ihre Trainingsziele mit integrierter Unterstützung für Nike + iPod
 
Sprachmemos
Nehmen Sie Notizen, Gedanken oder alles andere auf.
 
Bedienungshilfen
Der iPod touch kommt mit Bildschirmlesefunktion und weiteren Bedienungshilfen
 
Lieferumfang
iPod touch, Ohrhörer, USB 2.0 Kabel, Dock Adapter, Kurzanleitung
";2;False;0;;;"Apple iPod touch 4G 32 GB ";apple-ipod-touch-4g-32-gb;True;True;PD-01066;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;279.9900;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40637,445775463;45;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000615-apple-ipod-touch-4g-32-gb.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000616-apple-ipod-touch-4g-32-gb.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000617-apple-ipod-touch-4g-32-gb.jpg;1;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Apple iPod shuffle 2 GB 4G;"Der neue, bunte, tragbare iPod shuffle. Mit Tasten, VoiceOver und Wiedergabelisten - der beste iPod shuffle, den es je gab. ";"Der neue, bunte, tragbare iPod shuffle.
Mit Tasten, VoiceOver und Wiedergabelisten - der beste iPod shuffle, den es je gab.
 
Eingebauter Clip.

Sie ist wieder da - die große Klickbedienung vorn auf dem iPod shuffle.
 
Erhältlich in Silber, Blau, Grün, Orange und Pink.
 
Design. Ganz schön ansteckend.
Elegantes, poliertes Aluminium. Fünf leuchtende Farben.
Das Gehäuse des iPod shuffle ist aus einem Stück Aluminium. Und weil es außerdem poliert ist, können Sie mit dem neuen, eleganten und robusten iPod shuffle richtig glänzen. Seine brillanten Farben machen ihn dabei zum perfekten Accessoire. Wählen Sie zwischen Silber, Blau, Grün, Orange und Pink.
 
Hunderte Songs für unterwegs.
Nehmen Sie Ihre Lieblingssongs überallhin mit. Neben 15 Stunden Batterielaufzeit1 kommt der iPod shuffle mit 2 GB Speicher - das heißt Platz für hunderte von Songs. Genug für alle Songs für Ihr Fitness-Training oder den Weg zur Arbeit. Und auch für mehrere Wiedergabelisten, Genius Mixe, Podcasts und Hörbücher.
 
Geht immer. Und überall.
Der iPod shuffle ist nicht nur tragbar. Er ist auch ansteckbar. Klippen Sie ihn an Hemd, Jacke, Jogginghose, Rucksack oder Tasche und er ist überall mit dabei - egal, ob Sie zum Supermarkt laufen oder zu Ihrer persönlichen Bestzeit.
 
Bedienung. Musik auf Knopfdruck.

Steuern Sie Ihre Musik mit nur einem Klick.
Sie ist wieder da - die große Klickbedienung vorn auf dem iPod shuffle. Sie ist 18 Prozent größer als bei den Vorgängermodellen. So können Sie sie sie noch leichter sehen und bedienen. Drücken Sie auf die Mitteltaste, um die Wiedergabe zu starten oder zu stoppen. Drücken Sie auf die äußeren Tasten, um vor- und zurückzuspringen oder die Lautstärke anzupassen. Klick, klick, klick. Das ist Musik für Ihre Finger.
 
Spielt nach Ihren Regeln.
Sie sind eher ein spontaner Typ? Oder haben Sie vielleicht lieber Ihre Ordnung? Stellen Sie den Schalter für die Zufallswiedergabe so ein, wie Sie wollen. Links wird Ihre Musik zufällig durcheinander gewürfelt. In der Mitte werden Ihre Songs in der normalen Reihenfolge gespielt. Und rechts schalten Sie den iPod shuffle aus.
 
Geben Sie Ihren Songs eine Stimme.
Angenommen Sie hören einen Song und wollen den Titel oder den Interpreten wissen. Drücken Sie einfach oben auf deinem iPod shuffle auf die neue VoiceOver Taste und VoiceOver nennt Ihnen beides. VoiceOver nennt Ihnen auch die Namen Ihrer Wiedergabelisten und wechselt zwischen diesen. Und wenn die Batterie aufgeladen werden muss, sagt VoiceOver das auch.
 
Spricht Ihre Sprache.
Französische Chansons. Spanische Flamencos. Italienische Arien. Ihr Musikarchiv enthält Songs aus allen Ländern der Erde. Deshalb spricht VoiceOver 25 verschiedene Sprachen. Und kann Ihnen Songtitel und Interpreten in deren jeweiliger Landessprache oder einer anderen Sprache nennen.
 
Wiedergabelisten. Der perfekte Mix für jede Stimmung.
Ganz einfach synchronisieren.
Mit iTunes auf dem Mac oder PC können Sie Ihre Sachen ganz einfach auf den iPod shuffle laden. Wählen Sie einfach die Hörbücher, Wiedergabelisten, Podcasts und andere Audiodateien, die Sie wollen, und synchronisieren Sie sie.
 
Wenn eine Wiedergabeliste nicht reicht.

Wahrscheinlich haben Sie in iTunes auf Ihrem Computer mehrere Wiedergabelisten. Eine für unterwegs. Eine fürs Fitnessstudio. Eine zum Chillen. Jetzt können Sie diese Wiedergabelisten mit dem iPod shuffle synchronisieren und haben immer genau den richtigen Mix - egal, in welcher Stimmung Sie gerade sind. VoiceOver nennt Ihnen den Namen jeder Wiedergabeliste. So können Sie ganz leicht zwischen ihnen wechseln und genau die auswählen, nach der Ihnen gerade ist.
 
Genius auf dem iPod shuffle.

Und es gibt noch einen anderen Weg einen guten Mix auf den iPod shuffle zu bekommen: Verlassen Sie sich auf Genius. Aktivieren Sie Genius in iTunes auf dem Computer und er findet automatisch Songs, die gut zusammenpassen. Dann werden Genius Mixe erstellt, die Sie ganz einfach mit Ihrem iPod shuffle synchronisieren können. Das ist perfekt, um Songs zu entdecken, die Sie schon seit Jahrhunderten nicht mehr gehört haben.
 
Lieferumfang
iPod shuffle, Ohrhörer, iPod shuffle USB Kabel (4,5 cm), Dokumentation";2;False;0;;;Apple iPod shuffle 2 GB 4G;apple-ipod-shuffle-2-gb-4g;True;True;PD-01065;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;54.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40637,4367824074;41;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000600-apple-ipod-shuffle-2-gb-4g.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000601-apple-ipod-shuffle-2-gb-4g.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000602-apple-ipod-shuffle-2-gb-4g.jpg;1;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Nokia Lumia 800 Smartphone;Nokia Lumia 800 Smartphone (9,4 cm (3.7 Zoll) AMOLED Clear Black-Touchscreen, Micro-SIM only, Windows Phone Mango OS, 8 MP Kamera) schwarz;"
Einfacher ist besser.
Das Nokia Lumia 800 mit Windows Phone. Alle Aktivitäten Ihrer Kontakte auf einen Blick.
 
Startseite
Legen Sie Gruppen oder Kontakte auf der Startseite ab, um noch schneller auf sie zuzugreifen. Sie können beliebige Elemente auf der Startseite ablegen. Halten Sie einfach den Finger auf die gewünschten Apps oder Tools, bis das Menü „Auf Startseite“ angezeigt wird.
 
Gruppen
Die Gruppe „Familie“ ist im Kontakte-Hub vorkonfiguriert, damit Sie sofort loslegen können. Sie schlägt Ihnen Kontakte mit übereinstimmenden Namen als Gruppenmitglieder vor. Doch Sie können auch beliebige andere Gruppen als Kachel auf der Startseite ablegen. In diesen Kacheln werden Profilfotos, entgangene Anrufe und Status-Updates aller Kontakte dieser Gruppe anzeigt. Sofort nach einer Status-Änderung beginnt diese Kachel, sich in sich selbst zu drehen, damit Sie keine Nachricht mehr verpassen. Wenn Sie Ihre Kontakte leichter voneinander unterscheiden möchten, können Sie ihnen individuell oder als Gruppe eigene Klingeltöne zuweisen. Tippen Sie einfach auf das gewünschte Profil und dann auf das Stift-Symbol, um einen Klingelton zu bearbeiten und hinzuzufügen.
 
Immer tolle Fotos
Fotografieren war noch nie so einfach – betätigen Sie einfach den Auslöser. Sie müssen das Smartphone noch nicht einmal entsperren, um richtig tolle Fotos zu machen. Danach können Sie die Fotos ebenso schnell auf Facebook oder anderen sozialen Netzwerken veröffentlichen. Und die 5-Megapixel-Kamera mit Autofokus sorgt für brillante, detailreiche Fotos, die garantiert Eindruck machen.
 
Sprachgesteuerte Aktivierung
Halten Sie einfach die Windows-Taste gedrückt, um die Spracherkennung zu aktivieren. Sie können mithilfe von Sprachbefehlen Anrufe tätigen, Ihren Kalender aufrufen, Texte diktieren und sogar Internetrecherchen durchführen.
 
Multitasking
Halten Sie den Zurück-Pfeil gedrückt, um zu sehen, welche Anwendungen gleichzeitig ausgeführt werden. Profil
Nokia Lumia Smartphones sind automatisch mit Facebook verknüpft und verwenden Ihr Standard-Profilbild. Doch auch das können Sie im Handumdrehen ändern – tippen Sie einfach auf „Profil“, um ein neues Foto auszuwählen.
 
Nokia Lumia Smartphones und Bing
Starten Sie die Anwendung im Handumdrehen über das Symbol „Suchen“, um Internetrecherchen durchführen zu können, ohne den Browser zu öffnen. Geben Sie einfach Ihren Suchbegriff ein und wählen Sie das beste Ergebnis. Einfach. Intuitiv. Schnell.
 
Apps
Mit Wi-Fi laden Sie Apps mit größerem Dateiumfang, mobile Spiele und Medien noch schneller herunter. So können Sie das von Ihrem Provider ggf. im Rahmen eines Vertrags zur Verfügung gestellte Dateivolumen genau dann nutzen, wenn Sie es wirklich benötigen.
 
Xbox Live Avatar
In Xbox Live erstellen Sie ganz leicht einen Avatar für die Xbox Community. Öffnen Sie einfach Xbox Live und klicken Sie auf „Avatar“. Dort können Sie Ihrer Figur je nach Wunsch Frisur, Gesichtszüge und Kleider geben - auch als Abbild Ihrer selbst. Eben einfach die vielen kleinen Dinge, die Sie unverwechselbar machen. Lassen Sie Ihrer Kreativität freien Lauf und freuen Sie sich auf rasantes Gaming.
 
Musik kaufen
Mit Millionen von Songs zur Auswahl bietet Ihnen Nokia Musik jederzeit Zugriff auf die neuesten Hits und Ihre Lieblings-Klassiker. Nutzen Sie einfach die Suchfunktion oder stöbern Sie in den neuesten Veröffentlichungen. Wenn Sie sich entschieden haben, genügt eine Berührung, um den Song zu kaufen und in Ihre Bibliothek herunterzuladen.
 
Schnelle Steuerung
Wahrscheinlich möchten Sie noch mehr tun, als nur Musik zu hören. Deshalb ist es gut, dass Sie nicht jedes Mal Nokia Musik öffnen müssen, um zu einem anderen Song zu wechseln. Tippen Sie einfach auf die Lautstärkeregelung und unterbrechen oder überspringen Sie Songs über den Schnellzugriff. Das funktioniert auch, wenn das Smartphone gesperrt ist.
 
Aktuelle Wiedergabe
Über die Wiedergabeliste können Sie Musik aus Ihrer Bibliothek jederzeit individuell steuern - beispielsweise als zufällige Wiedergabe oder als Dauerschleife.
 
Sprachgestützte Navigation
Die Nokia Navigation mit gesprochenen Richtungsanweisungen ist auf Ihrem Nokia Lumia Smartphone vorinstalliert. Ihnen gefällt die Stimme nicht? Dann ändern Sie einfach die Ansagestimme der Navigation oder laden Sie eine neue herunter. Öffnen Sie dazu die Einstellungen und wählen Sie die Stimme, die Ihnen am angenehmsten ist.
 
Tag und Nacht
Sie werden bei Nachtfahrten nie wieder durch Ihr Navigationssystem geblendet. Mit der Nokia Navigation können Sie die Helligkeit des Displays anpassen, ohne dadurch die Deutlichkeit der Anzeige zu beeinträchtigen.
 
2D und 3D
Die Nokia Navigation bietet sowohl 2D- als auch 3D-Kartenansichten. Wenn Sie also eine genauere Ansicht Ihrer Route benötigen oder nach einprägsamen Orientierungspunkten Ausschau halten möchten, können Sie die Ansicht einfach über die Einstellungen ändern.
 
Nokia Karten herunterladen
Nokia Karten ist nach wenigen Handgriffen auf Ihrem Smartphone einsatzbereit. Diese App beinhaltet kostenlose Reiseführer, Veranstaltungstipps, interessante Ziele in Ihrer Nähe, Wetterinfos und vieles mehr. Öffnen Sie die Karten-Kachel, rufen Sie Marketplace auf und starten Sie den Download – die Anwendung ist kostenlos. Nach der Installation können Sie Nokia Karten über 3G- oder WLAN-Verbindungen nutzen.
";2;False;0;;;Nokia Lumia 800 Smartphone;nokia-lumia-800-smartphone;True;True;P-0006;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;499.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40603,5677546296;"74;2095";17;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000534-nokia-lumia-800-smartphone.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000535-nokia-lumia-800-smartphone.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000536-nokia-lumia-800-smartphone.jpg;1;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Nokia N9 Smartphone blau;Nokia N9 Smartphone (9,9 cm (3,9 Zoll) Display, 16GB, Touchscreen, 8 Megapixel Kamera) blau;"
Nokia N9 Smartphone
Formatfüllender Touchscreen
Ein einzigartiges Smartphone mit formatfüllendem Touchscreen. Die gewölbte Oberfläche aus kratzfestem Glas geht nahtlos in das glatte, aus einem Block gefertigte Gehäuse über. Jedes Detail strahlt Innovation aus. Auf dem brillanten AMOLED-Touchscreen erscheint alles in lebendigen Farben und das gewölbte Glas macht den Wechsel zwischen Apps per Fingerbewegung zum Kinderspiel.
 
Einfach nur eine Fingerbewegung - Überzeugend benutzerfreundlich
Alles läuft auf eine einfache Fingerbewegung hinaus. Das macht die Nutzung dieses Smartphones so intuitiv wie nie zuvor. Es gibt keine Zurück- oder Menü-Taste mehr – nur fliessende Fingerbewegungen, während Sie von App zu App wechseln. Mit einer Fingerbewegung über eine beliebige Ecke des Touchscreens gelangen Sie zur Startansicht, mit einer weiteren Bewegung wechseln Sie zwischen den drei Startansichten.
 
Eine Startansicht - Drei einfache Ansichten
Drei Ansichten sind alles, was Sie brauchen. In der vertrauten App-Ansicht starten Sie Anwendungen, eine weitere Ansicht zeigt die offenen Apps und macht Multitasking zum Kinderspiel: Sie machen genau dort weiter, wo Sie aufgehört haben.- Die Ansicht ""Ereignisse"" bringt Sie jederzeit auf den neuesten Stand der Dinge. Live-Feeds von Facebook und Twitter, E-Mails in Echtzeit, RSS-Feeds und mehr – alles an einer Stelle.
 
Karten und Navigation kostenlos
Live-Feeds von Facebook und Twitter, E-Mails in Echtzeit, RSS-Feeds und mehr – alles an einer Stelle. Sie finden die besten Angebote in Ihrer Stadt wie Cafés, Geschäfte, Konzerte, Hotels und mehr. Für mehr als 80 Städte weltweit steht Ihnen eine Übersicht von Strecken und Haltestellen des öffentlichen Nahverkehrs zur Verfügung. Entsprechendes Kartenmaterial ist bereits vorinstalliert, sodass Sie sofort starten können. Die Anwendung ""Fahren"" ist dank einfacher Bedienung über Touchscreen für die Verwendung im Auto optimiert.
 
Browser der nächsten Generation
Zeit für mehr Tempo. Das Nokia N9 bietet einen schnellen mobilen Internet-Browser und Seiten werden in kürzester Zeit aufgebaut. Die Unterstützung für HTML5 bedeutet für Sie das Beste aus dem Web, inklusive interaktiver Apps und schneller Videowiedergabe. Der Browser reagiert schnell auf jede Berührung. Sie können mehrere Seiten gleichzeitig öffnen und schnell zwischen den Seiten wechseln.
 
 
 
8-Megapixel-Kamera mit Optik von Carl Zeiss
Die Gelegenheit für ein gutes Foto kommt schnell und ist ebenso schnell vorbei. Mit der integrierten 8-Megapixel-Kamera mit Optik von Carl Zeiss können Sie brillante Fotos oder Videos in herausragender HD-Qualität aufnehmen.
 
Die besten Apps und Spiele
Apps sind heutzutage allgegenwärtig. Das Wichtigste ist jedoch die Qualität und nicht, wie viele man besitzt. Auf dem Nokia N9 sind die besten Apps wie Skype, Facebook, Twitter, AccuWeather und AP Mobile bereits vorinstalliert. Auch die Vollversion von Angry Birds ist bereits vorinstalliert – für viele Stunden Spass. Und im Ovi Store gibt es viele weitere Apps und Spiele.
";2;False;0;;;Nokia N9 Smartphone blau;nokia-n9-smartphone-blau;True;True;P-0008;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;569.0000;569.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40602,8930439815;74;17;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000280-nokia-n9-smartphone-blau.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000281-nokia-n9-smartphone-blau.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000282-nokia-n9-smartphone-blau.jpg;1;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Apple iPod Nano 8 GB verschiedene Farben;Apple iPod Nano 8 GB;"
Apple iPod Nano 8 GB
 
 
Neues gebogenes Design, der dünnste iPod, den es je gab mit neuen Farben zu Auswahl
Die Bedieung optimiert: ein einziges Handschütteln und ein anderes Lied wird gespielt
Die neue Funktion ""Genius"" findet die Songs in Ihrer Mediathek, die besonders gut zusammenpassen, und erstellt daraus eine Genius Wiedergabeliste.
Viele Abspielformate: z.B. MP3, AAC, Apple Lossless, AIFF, WAV, H.264, MPEG-4
Lieferumfang: iPod Nano, Ohrhörer, USB 2.0 Kabel, Dock-Adapter, Dokumentation
 
Neues gebogenes Design, der dünnste iPod, den es je gab mit neuen Farben zu Auswahl
Die Bedieung optimiert: ein einziges Handschütteln und ein anderes Lied wird gespielt
Die neue Funktion ""Genius"" findet die Songs in Ihrer Mediathek, die besonders gut zusammenpassen, und erstellt daraus eine Genius Wiedergabeliste.
Viele Abspielformate: z.B. MP3, AAC, Apple Lossless, AIFF, WAV, H.264, MPEG-4
Lieferumfang: iPod Nano, Ohrhörer, USB 2.0 Kabel, Dock-Adapter, Dokumentation
 
Ein musikalisches Genie
Stell Dir vor, Du hörst einen Song. Toll wären jetzt andere Titel, die gut dazu passen. Was machst du? Ganz einfach: Du verwendest die neue Funktion ""Genius"". Diese findet die Songs in Deiner Mediathek, die gut zusammenpassen. Du erhältst eine Genius Wiedergabeliste, zusammengestellt von Deinem persönlichen, superintelligenten DJ.  
Musik schneller finden
Auch einen Song, den Du hören willst, findest Du jetzt viel einfacher. Du kannst Deine Alben mit Cover Flow anzeigen oder hältst einfach die mittlere Taste gedrückt und blätterst in Deinen Alben oder Interpreten. Den gewünschten Song gefunden? Einmal auf die mittlere Taste gedrückt, und schon hast Du ihn zur aktuellen Wiedergabeliste hinzugefügt. 
 
Aufdrehen und rumdrehen
Neige Deinen iPod nano in die Waagerechte, und schon kannst Du hören, sehen oder spielen wie nie zuvor. Deine Alben kannst Du mit Cover Flow durchblättern und siehst so viel mehr Alben oder Interpreten gleichzeitig auf dem Display.
 
Shake it, Baby!
Manchmal hat man einfach Lust auf eine kleine Überraschung. Darum kannst Du jetzt komplett dem Zufall überlassen, welches Lied Du als Nächstes hörst. Einfach den iPod nano kurz schütteln – und er springt zu irgendeinem anderen Song aus Deiner Musik-Bibliothek. Lass dich überraschen, was er Dir als Nächstes präsentiert.   
Spiel ab!
Jetzt kannst Du Dir mit Spielen die Zeit vertreiben, die ganz speziell auf den iPod nano und den Beschleunigungssensor zugeschnitten sind. Sie reagieren auf Deine Bewegungen und wirken dadurch so überzeugend, dass sie fast schon süchtig machen können. In jedem Fall wirst Du begeistert sein. Bereits vorinstalliert ist Maze, wo Du Dich durch Neigen, Kippen und allerlei andere Bewegungen durch riesige Labyrinthe manövrieren musst. Im iTunes Store stehen natürlich noch viele weitere Spiele zur Auswahl.
 
Sogar Deine Fotos rocken
Jetzt kannst Du gleich hunderte von Fotos aus der Tasche zaubern und überall vorführen. Senkrecht gehalten zeigt der iPod nano Deine Fotos im Hochformat an, wenn Du ihn um 90 Grad drehst, wechseln auch die Fotos ins Querformat. Die Fotos wirken in ihrem richtigen Größen- und Seitenverhältnis auf dem brillanten Display mit 320 x 240 Pixeln einfach hervorragend. 
Der größte kleine Bildschirm der Welt
Filme, Fernsehsendungen und Videos auf dem iPod nano anzusehen, ist das pure Vergnügen. Die hochauflösende Anzeige wirkt auf dem kristallklaren 2"" Breitbild-Display besonders brillant und lebendig. So hast Du mit dem iPod nano Dein eigenes Kino im Taschenformat immer dabei.  
 
Produktbeschreibungen
Flach, flacher, am flachsten mit nur 6,2mm bringt der iPod nano, in leuchtenden Farben, neuen Schwung ins Leben.
Mit brilianterem Display, höherer Speicherkapazität und noch längerer Batterielaufzeit schütteln Sie sich einfach durch Ihre Mediathek.
Leistungsmerkmale
- Verschieden Menüs: Musik, Fernsehsendungen, Videos, Hörbücher, Podcasts, Diashows, Spiele
- Geschwungenen Aluminium-Design mit gewölbtem Glas
- HxBxT: 90,7 x 38,7 x 6,2 mm
- Gewicht: 36,8 g
Lieferumfang
- iPod nano
- Ohrhörer
- USB 2.0-Kabel
- Dock-Adapter
- Dokumentation
Display
- 2- Farb-LCD mit LED-Hintergrundbeleuchtung
- 320 x 240 Pixel
Kapazität
- 8 GB Flash-Laufwerk1 für bis zu 2.000 Songs, 7.000 Fotos, 8 Std. Videomaterial
Batterie
- Integrierte, wiederaufladbare Lithium-Ionen-Batterie
- Musikwiedergabe: bis zu 24 Stunden bei voller Ladung
- Videowiedergabe: bis zu 4 Stunden bei voller Ladung
Audio
- Unterbrechungsfreie Wiedergabe
- Frequenzbereich: 20 Hz bis 20.000 Hz
- Unterstützte Audioformate: AAC, Protected AAC, MP3, MP3 VBR, Audible, Apple Lossless, AIFF und WAV
Systemvoraussetzungen
- USB 2.0-Anschluss
- mind. Mac OS X 10.4.11 bzw. mind. Windows Vista oder Windows XP Home oder Professional
- mind. iTunes 8  

 
 
 
";2;False;0;;;Apple iPod Nano 8 GB;apple-ipod-nano-8-gb-verschiedene-farben;True;True;P-1371;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;139.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40218,6740856481;47;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000075-apple-ipod-nano-8-gb-verschiedene-farben.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000076-apple-ipod-nano-8-gb-verschiedene-farben.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000077-apple-ipod-nano-8-gb-verschiedene-farben.jpg;1;;False;;;;;False;False;False;;;;;False;;;;;; -5;210;True;_SmartStore.biz 6;Das Shopping System;"
SHOP
Mit neuesten Technologien topmoderne Ergebnisse erzielen
Durch konsequente Verwendung von HTML5, CSS3, jQuery und jQuery UI erzeugt SmartStore.biz 6 schnelle und übersichtliche Seiten. Erst kürzlich hat auch YouTube sein Portal mit diesen Technologien neu aufgestellt. Das jQuery Framework bietet komfortable Funktionen zur Manipulation von Webseiten. jQuery UI ist eine Erweiterung von jQuery und bietet Lösungen zur Gestaltung und Funktionalität der Benutzeroberfläche an.
Zusammen mit HTML5 und CSS können mit diesen Technologien komplexe Seiten hochperformant erstellt werden. Komponenten aus der jQuery UI-Bibliothek passen sich automatisch SmartStore-Theme Designs an. So können Sie selbst Komponenten und Effekte aus jQuery UI einbinden.
Facebook, Google & Co
Soziale Interaktion und Zusammenarbeit belebt den Shop und bindet Besucher. SmartStore.biz 6 bietet Möglichkeiten für die Verwendung von allen wichtigen Plattformen.
Kunden können mit Google+ und Facebook Like Ihren Shop weiterempfehlen oder über Facebook Kommentare ein Kommentar zu einem Ihrer Angebote verfassen, welcher dann auch auf der Facebook-Seite des Kunden erscheint.
Megamenü Navigation
Mehrspaltige Menüs werden immer beliebter. Die Megamenü Navigation bietet gegenüber der einfachen Dropdown Navigation größere Navigationsflächen und die Darstellung von mehreren Navigationsebenen auf einer Ebene.
Shrinkmenü
Klein aber fein. Navigationsleisten mit sehr vielen Einträgen werden oft unzureichend gut dargestellt. Meist werden Einträge abgeschnitten oder alle Einträge werden angezeigt und das Layout passt nicht mehr.
Die Funktion „Shrinkmenu“ passt die Navigation so an, dass der Platz für die Navigation optimal genutzt wird.
Produktliste
Eine Produkliste führt sämtliche Produkte eines Shops auf. Die neue Produktliste in SmartStore.biz 6 stellt Produkte wahlweise in einer mehrspaltigen Galerieansicht und in einer Listenansicht dar.
Produktdetail
Das neue Produktdetail-Modul zeigt jetzt alle zum Produkt zugehörigen Bilder in einer Galerie dar. Eine Zoom-Ansicht, in der die Bilder-Galerie in Vollbild angezeigt wird und eine Vollbild-Ansicht, in der jeweils ein Bild in einer LightBox angezeigt, erlauben Ihnen eine detaillierte und schöne Produktpräsentation. In der Vollbild-Ansicht kann zudem, ohne diese Ansicht zu verlassen zu anderen Bildern navigiert werden.
Durch die Verwendung des Tab-Moduls können Daten wie Produktbeschreibung aber auch andere Module übersichtlich dargestellt werden.
Docked Minibasket
Der neue interaktive Mini-Warenkorb dockt sich stets griffbereit in die Fußzeile des Shops an. Der Shop-Kunde kann nicht nur per Knopfdruck, sondern auch per Drag & Drop seine Waren in den Warenkorb legen.
Die detaillierte Ansicht des Warenkorbs verschafft dem Käufer stets einen klaren Überblick über seine Einkaufsliste. Derartige Design Highlights  erzeugen beim Käufer Sympathiepunkte, die sich in den meisten Fällen verkaufsfördernd auswirken.
Tabs
Das neue Tab-Modul stellt beliebige Module in Tabs dar und ermöglicht somit eine übersichtliche Darstellung von vielen Inhalten. Inhalte können so platzsparend und übersichtlich bei minimalem Platzverbrauch angezeigt werden. Überlange Seiten und langes scrollen gehören damit zur Vergangenheit.
  
Splitter
Der neue Splitter ermöglicht es, beliebig viele Module horizontal anzuordnen. Inhalten werden so platzsparend und ansprechend dargestellt.
Content-Slider
Der Content-Slider macht aus beliebigem Inhalt auf der Seite eine Dia-Show.
Stellen Sie Top-Produkte, Sonderangebote und News eindrucksvoll mit einem Conten-Slider dar. Viele hübsche und effektvolle Übergangseffekte, Auto-Slide-Modus und die Paginierung machen den Content-Slider zu einem Hingucker in Ihrem Shop. 
THEMING & DESIGN
Neue Themes
Smartstore.biz 6 enthält zwei von Grund auf neu entwickelte Themes. Ein modernes und ansprechendes Shop-Design ist somit "out-of-the-box" garantiert!
60 neue Banner-Grafiken
60 neue Banner-Grafiken aus unterschiedlichen Themenbereichen bilden die Grundlage für schicke und harmonische Banner. Mit den neuen Editierfunktionen lassen sich so hervorragende Banner mühelos mit ein paar Klicks erstellen.
Seiten-Layout
Das neue Seitenlayout basiert auf dem 960 Grid System.
Per Knopfdruck kann das Layout eines Themes verändert werden. Layout-Typen wie Feste Breite, Hybrid und Dynamisch können sofort auf jedes Theme angewendet werden.
Darüber hinaus können Außen- und Innenabstände, die Ausrichtung und die Breite der Seite einfach eingestellt werden.
HTML Container
HTML Container sind „Behälter“ für andere HTML-Elemente und dienen zur optischen Ausgestaltung. Container schaffen Übersicht und setzen Akzente.
SmartStore.biz 6 enthält eine Container-Bibliothek mit mehr als 60 modern gestalteten Containern, die sich beliebig mit jedem Theme kombinieren lassen.
Banner-Editor
Der neue Banner-Editor bietet jetzt Ausblendeffekte für Ihren Banner nach allen Seiten und intelligente Spiegelungsfunktionen. Banner können nach allen Seiten mit eleganten Ausblendeffekten versehen werden und erzielen. Mit den neuen Editierfunktionen lassen sich so hervorragende Banner mühelos mit ein paar Klicks erstellen.
WEITERE HIGHLIGHTS
User Interface
Innerhalb von SmartStore.biz 6 wurden die Funktionen in vielen Bereichen verbessert.
Die Benutzeroberfläche wurde auf den neusten Stand gebracht.
Alle wichtigen Menü-Einträge und Funktionen sind nun über ein anpassbares, Office 2010 ähnliches Ribbon erreichbar.
Page-Designer
Der Page-Designer wurde grundlegend Überarbeitet. Zur Übersichtlichkeit lassen sich nun Module auf- und zuklappen. Die Bedienung per Drag & Drop wurde intuitiver gestaltet.
Multipanel Module
Multipanel Module erzeugen aus anderen Modulen neue Darstellungen. So können z.B. aus vielen Bildern Galerien erzeugt werden oder eine Sammlung von Bildern, Buttons und Eingabefeldern kann in einem Tab dargestellt werden.
SmartStore.biz 6 beinhaltet die Multipanel Module Tab, Splitter und Content-Slider.
Ereigniskonsole
Die Ereigniskonsole zeigt Fehlermeldungen und Ereignisse beim Testen und Erstellen an.
Mit ihr lassen sich leicht Fehler in Skripten, Modulen und Plug-Ins finden. Fehler werden mit einer Beschreibung, dem Zeitpunkt des Auftritts, dem Fehler-Typ und dem Ursprung der Meldung angezeigt.
Designer und Entwickler bekommen so direkt ein Feedback über Fehler. Über Aufrufe in eigenen Anwendungen können Entwickler Zeitmessungen vornehmen oder beliebige Nachrichten in der Ereigniskonsole anzeigen
Payment-Schnittstellen
masterpayment Zahlungsschnittstelle
MASTERPAYMENT bietet das Rundum-Sorglos-Paket wie Rechnungskauf, Kreditkarte, Ratenzahlung, Sofortüberweisung jetzt für SmartStore-Händler an.
Wer in seinem SmartStore-Shop MASTERPAYMENT bis zum 31.12.2011 aktiviert, spart sich sämtliche Grundgebühren und Set-Up-Gebühren für alle Zahlarten!
Klarna Zahlungsschnittstelle
Mit Klarna Rechnung und Ratenkauf anbieten!
Klarna ist Europas führender Anbieter von rechnungsbasierten Zahlungs- und Finanzierungslösungen im Internethandel. Rechnung und Ratenkauf mit Klarna bieten Onlineshoppern entscheidende Vorteile.
BillSafe Zahlunsschnittstelle
Mit BillSAFE bieten Sie Ihren Kunden die beliebteste Zahlart in Deutschland – den Kauf auf Rechnung! Dadurch steigern Sie Ihren Umsatz, gewinnen
neue Käufergruppen und erhöhen den Anteil an Bestandskunden. Das alles geht mit
BillSAFE völlig ohne Ausfallrisiko..
";2;True;0;;;SmartStore.Biz 6;_smartstorebiz-6;True;True;P-6000;;MYEAN-65487;False;0;False;;False;False;0;True;0;1;False;;False;;False;100;0;10;True;False;0,0000;False;False;1;2;10000;True;True;0;0;0;0;False;1;10000;;False;False;False;False;190.0000;0.0000;0.0000;166.0000;42248,5157986111;42250,9999884259;False;100.0000;200.0000;0.0000;0.0000;0.0000;0.0000;40218,6501736111;"29;78;81;2095";42;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000070-_smartstorebiz-6.png;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000071-_smartstorebiz-6.png;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000072-_smartstorebiz-6.png;3;1;True;kg;2.0000;1;;False;False;False;;;;;False;;Toll Software DE;"

Langbeschreibung

";SmartStore Biz EN;Nice software;"

Long descriiption

" -5;0;True;Sandisk Sansa Clip 2 GB rot;Sandisk Sansa Clip 2 GB mit integriertem FM-Tuner rot;"

Sandisk Sansa Clip 2 GB mit integriertem FM-Tuner rot

digitaler SanDisk Player für MP3, WMA, Secure WMA und FM Radio
kleines, kompaktes Design, kaum größer als eine Streichholzschachtel
FM-Radio mit 40 Stationsspeicherplätzen
Diktiergerät-Funktion über integriertes Mikrofon
4-zeiliges OLED-Display
 
Sortierung der Titel nach versch. Kriterien möglich, wie z.B. Künstler, Album, Genre, u.a.
bis zu 15-h-Wiedergabe mittels internem, wiederaufladbaren Akku
inkl. abnehmbarem Trageclip, Ohrhörer, USB 2.0 Kabel, Installations-CD mit Bedienungsanleitung
unterstützt Win 2000 / XP / Vista
 
Lieferumfang:
Player inkl. abnehmbarem Trageclip, Ohrhörer, USB 2.0 Kabel, Installations-CD mit Bedienungsanleitung
";2;False;0;;;"Sandisk Sansa Clip 2 GB mit integriertem FM-Tuner ";sandisk-sansa-clip-2-gb-rot;True;True;P-1620;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;42.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40206,8077430556;52;8;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000571-sandisk-sansa-clip-2-gb-rot.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Sandisk Sansa Fuze 8 GB silber;"Sandisk Sansa Fuze MP3-/Video-Player 8 GB mit Radio silber ";"

Sandisk Sansa Fuze MP3-/Video-Player 8 GB mit Radio silber

 
 
Mit der verfügbaren Akkuleistung können Sie 24 Stunden lang Musik hören, Bilder anschauen oder spielen.
Der neue Sansa Fuze von SanDisk ist der ideale tragbare Musikplayer für Sie.
Er steht mit einer Speicherkapazität 4 GB in schwarz,rot,pink zur Verfügung.
Sehen Sie sich Ihre Lieblingsvideoclips auf dem 1,9""-Farbdisplay des Sansa Fuze an.
Lauschen Sie dem FM-Radio mit 40 voreingestellten Sendern oder probieren Sie den integrierten Sprachrekorder aus. Mit einer unglaublich starken Akkuleistung in einem 0,3"" schmalen Gerät setzt der Sansa Fuze Zeichen.
";2;False;0;;;Sandisk Sansa Fuze MP3-/Video-Player 4 GB mit Radio;sandisk-sansa-fuze-8-gb-silber;True;True;P-1610;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;89.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40206,8019444444;52;8;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000570-sandisk-sansa-fuze-8-gb-silber.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Asus Eee PC 1001HA 10,1 Zoll Netbook;Asus Eee PC 1001HA 10,1 Zoll Netbook;"
Eee PC™ 1001HA: Klasse Leistung zu unschlagbarem Preis
 
Der Eee PC™ 1001HA unterscheidet sich von seinen großen Brüdern durch Prozessor und Akkukapazität. Ausgestattet mit einem Intel® Atom™ N270 Prozessor, einem 3 Zellen Akku für bis zu 4 Stunden Laufzeit, WLAN 802.11n Standard sowie weiteren Top Merkmalen, überzeugt der Eee PC™ 1001HA zu einem wirklich unschlagbaren Preis.
 
Eee PC™ 1001HA: Funktionalität meets Design
 
Mit dem kompakten Eee PC™ 1001HA trägt ASUS seinem Anspruch, in den Produkten höchste Funktionalität mit formvollendetem Design zu verbinden, ein weiteres Mal Rechnung. So besticht der neue Eee PC™ durch sein elegantes und gleichzeitig unempfindliches Gehäuse, das mit klaren Linien und nach unten schmaler zulaufenden Kanten dem schlanken Design einer Muschel nachempfunden ist. Aber auch das Innenleben der Kleinen kommt ganz groß raus. Als gewohnt kontaktfreudig erweisen sich die Neulinge dank VGA Port für den Anschluss eines Monitors sowie drei USB 2.0 Schnittstellen, um Maus, Tastatur oder Digicam anzuschließen. Wer Bilder direkt von der SD oder MMC Speicherkarte auf den Eee PC™ übertragen möchte, nutzt den integrierten Kartenleser. Für das Speichern der Fotos stehen bei beiden Modellen eine 160 GB S-ATA Festplatte zur Verfügung.. Das Modell basiert auf Microsoft® Windows® XP Home und ist – wie alle Eee Familienmitglieder – ausgesprochen einfach zu bedienen. Das 10 Zoll WSVGA Display mit stromsparender LED-Hintergrundbeleuchtung sowie die große Tastatur, die zu 92% einer Standard Notebooktastatur entspricht, gewähren zusätzlichen Komfort. Für Chats oder Videokonferenzen hat ASUS die Minis zudem mit einer 0.3 Megapixel Web-/Videokamera sowie einem Mikrofon ausgestattet.
 
 
";2;False;0;;;Asus Eee PC 1001HA 10,1 Zoll;asus-eee-pc-1001ha-101-zoll-netbook;True;True;P-0890;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;243.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40205,9519907407;6;37;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000563-asus-eee-pc-1001ha-101-zoll-netbook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000564-asus-eee-pc-1001ha-101-zoll-netbook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000565-asus-eee-pc-1001ha-101-zoll-netbook.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Canon PGI 520BK Tintenpatrone schwarz;Canon PGI 520BK Tintenpatrone schwarz;"
Canon PGI 520BK ,Tintenpatrone, schwarz, 19ml
 
 
 
kompatibel  PIXMA iP3600/iP4600/IP4700 und MP540/620/630/640

 
 
";2;False;0;;;"Canon CLI-521, Tintenpatrone, cyan, 9ml, für PIXMA iP3600/iP4600/IP4700 und MP540/620/630/980 - ""R"" ";canon-pgi-520bk-tintenpatrone-schwarz;True;True;P-2280;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;-1,2000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;11.9900;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40205,7303009259;23;25;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000562-canon-pgi-520bk-tintenpatrone-schwarz.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Canon CLI-521 Tintenpatrone schwarz;Canon CLI-521 Tintenpatrone;"
Canon CLI-521BK,Tintenpatrone, schwarz, 9ml
 
 
 
kompatibel  PIXMA iP3600/iP4600/IP4700 und MP540/620/630/640

 
 
";2;False;0;;;"Canon CLI-521, Tintenpatrone, cyan, 9ml, für PIXMA iP3600/iP4600/IP4700 und MP540/620/630/980 - ""R"" ";canon-cli-521-tintenpatrone-schwarz;True;True;P-2270;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;-1,2000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;11.9900;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40205,7265509259;23;25;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000555-canon-cli-521-tintenpatrone-schwarz.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Canon CLI-521 Tintenpatrone magenta;Canon CLI-521 Tintenpatrone;"
Canon CLI-521M,Tintenpatrone, magenta, 9ml
 
 
 
kompatibel  PIXMA iP3600/iP4600/IP4700 und MP540/620/630/640

 
 
";2;False;0;;;"Canon CLI-521, Tintenpatrone, cyan, 9ml, für PIXMA iP3600/iP4600/IP4700 und MP540/620/630/980 - ""R"" ";canon-cli-521-tintenpatrone-magenta;True;True;P-2260;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;-1,2000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;11.9900;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40205,7246643519;"23;2095";25;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000554-canon-cli-521-tintenpatrone-magenta.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Canon CLI-521 Tintenpatrone cyan;Canon CLI-521 Tintenpatrone;"
Canon CLI 521C,Tintenpatrone, cyan, 9ml
 
 
 
kompatibel  PIXMA iP3600/iP4600/IP4700 und MP540/620/630/640

 
 

 
 
";2;False;0;;;"Canon CLI-521, Tintenpatrone, cyan, 9ml, für PIXMA iP3600/iP4600/IP4700 und MP540/620/630/980 - ""R"" ";canon-cli-521-tintenpatrone-cyan;True;True;P-2250;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;-1,2000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;11.9900;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40205,7210416667;23;25;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000553-canon-cli-521-tintenpatrone-cyan.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Canon CLI-521 Tintenpatrone gelb;Canon CLI-521 Tintenpatrone;"
Canon CLI-521Y,Tintenpatrone, gelb, 9ml
 
 
 
kompatibel  PIXMA iP3600/iP4600/IP4700 und MP540/620/630/640

 
 
";2;False;0;;;"Canon CLI-521, Tintenpatrone, cyan, 9ml, für PIXMA iP3600/iP4600/IP4700 und MP540/620/630/980 - ""R"" ";canon-cli-521-tintenpatrone-gelb;True;True;P-2240;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;-1,2000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;11.9900;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40205,6889814815;23;25;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000552-canon-cli-521-tintenpatrone-gelb.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Philips DC 200 iPod Soundsytem ";"Philips DC 200 iPod Soundsytem ";"
Philips DC 200 iPod Soundsytem  - Radio, USB, Apple iPod kompatibel

Genießen Sie Ihre MP3-Lieblingsmusik auch beim Aufladen Ihres iPods! Dank der Docking-Station können Sie Ihren iPod direkt an das Docking-Entertainment-System anschließen und Ihre Lieblingsmusik in ausgezeichneter Soundqualität wiedergeben.
 
Ihr iPod wird während der Wiedergabe aufgeladen, sodass Sie Ihre Musik genießen können, ohne sich Gedanken über den Ladestand des Akkus machen zu müssen. Verwenden Sie zum Durchsuchen, Auswählen und Wiedergeben der auf dem iPod gespeicherten Musiktitel die Fernbedienung.
 
Das Docking-Entertainment-System lädt Ihren iPod automatisch auf, solange er sich in der Station befindet.
Durch den direkten USB-Anschluss können Sie einfach Musik auf einem USB-Gerät auswählen und wiedergeben.
Um Musik wiederzugeben oder Inhalte zu exportieren, stecken Sie das USB-Gerät einfach ein.
Das digitale UKW-Radio bietet Ihnen zusätzliche Musikoptionen für die Musiksammlung auf Ihrem Philips Player.
Stellen Sie einfach den gewünschten Radiosender ein, und halten Sie die Speichertaste gedrückt, um die Frequenz zu speichern.
 
Dank der voreingestellten und gespeicherten Radiosender können Sie ganz einfach Ihren Lieblingssender hören,
ohne die Frequenz jedes Mal manuell einstellen zu müssen.
 
Das Bassreflex-Lautsprechersystem sorgt bei kompakten Lautsprecher-Systemen für tiefe Bässe.
Der Unterschied zu konventionellen Lautsprecher-Systemen liegt in der Tiefbassröhre, die akustisch auf den Woofer abgestimmt ist,
 
um den Low Frequency Roll Off des Systems zu optimieren. Ergebnis sind tiefer gesteuerte Bässe und weniger Verzerrung.
 
Das Prinzip besteht darin, dass die Luftmasse in der Tiefbassröhre mitschwingt und wie ein herkömmlicher Woofer vibriert.
 
In Kombination mit der Reaktion des Woofers erweitert das System alle niederfrequenten Töne und erzeugt tiefe Bässe in einer völlig neuen Dimension.
 
Lieferumfang: 3,5 mm Stereo-Line-Eingangskabel;AC/DC-Adapter;Schnellstartanleitung;Benutzerhandbuch
";2;False;0;;;;philips-dc-200-ipod-soundsytem;True;True;P-1540;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;82.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40203,8622569444;"51;2095";6;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000544-philips-dc-200-ipod-soundsytem.jpg;;;1;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Logitech G500 Gaming Maus ";"Logitech G500 Gaming Maus ";"
 Logitech G500 Gaming Maus
 
 
 
Der spieletaugliche Laser geben Ihnen bei jeder Bewegungsgeschwindigkeit eine atemberaubende Präzision
Durch Feintuning mit bis zu 27 Gramm an zusätzlichen Gewichten bestimmen Sie exakt, wie die Maus in der Hand liegt
 
Der integrierte Speicher ermöglicht es Ihnen, die Einstellungen für Dein Lieblingsspiel zu speichern und mitzunehmen – es ist keine Software erforderlich

Das Tastenrad bietet Ihnen zwei Einstellungen – den präzisen Click-to-Click-Modus oder hyperschnelle Bildläufe
 
Lieferumfang:
Logitech G500 Gaming Maus, Anpassbares Gewichtsmagazin, Tuninggewichte und Etui, Bedienungsanleitung
";2;False;0;;;"Logitech G500 Gaming Maus ";logitech-g500-gaming-maus;True;True;P-2820;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;59.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40203,8042476852;21;11;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000543-logitech-g500-gaming-maus.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Garmin nüvi 205 Navigationssystem DACH;Garmin nüvi 205 Navigationssystem DACH;"
Garmin nüvi 205 Navigationssystem DACH
 
 
3,5 Zoll Touchscreen Display, PhotoNavigation, MicroSD-Kartenslot und ecoRoute
 
 
Bedienerfreundliches Einsteigernavigationsgerät mit elegantem, ultra-schlankem Design
und brillantem 3,5 Zoll (8,9cm Bilddiagonale) Touchscreen Display
Detailkarten für Deutschland, Österreich, Schweiz + CZ intern vorinstalliert
ecoRoute: reduziert den Kraftstoffverbrauch, CO2-Emissionen
und schont die Umwelt, spart bares Geld und füllt die Reisekasse auf.
PhotoNavigation mit Garmin Connect: Sie können Sehenswürdigkeiten und Bilder herunterladen und als Ziel auswählen
Lieferumfang: Garmin nüvi 205 mit Kartenmaterial DACH,
Saugnapfhalterung für die Windschutzscheibe, Armaturenhalterung, Schnellstartanleitung, KFZ-Anschlusskabel
";2;False;0;;;Garmin nüvi 205 Navigationssystem DACH;garmin-nuevi-205-navigationssystem-dach;True;True;P-2110;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;139.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40200,8638078704;67;44;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000542-garmin-nuvi-205-navigationssystem-dach.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"AVM FRITZ!Fon C3 VoIP Dect-Telefon ";"AVM FRITZ!Fon C3 VoIP Dect-Telefon ";"
FRITZ!Fon C3: HD-Telefonie und komfortable Internetdienste mit DECT.
Telefonieren Sie mit dem Schnurlostelefon FRITZ!Fon C3 in bestechender Qualität über das Internet und nutzen Sie komfortable Webdienste. Als intelligentes Telefon der neuesten DECT-Generation vereint das FRITZ!Fon den Komfort der schnurlosen Telefonie mit den Qualitäts- und Leistungsmerkmalen der Internettelefonie (VoIP) in einem Gerät.
 
Bei der Internettelefonie mit einem FRITZ!Fon wird durch HD-Telefonie (High Definition) ein brillantes, natürliches Klanggefühl erreicht. Sprache lässt sich mit dem FRITZ!Fon in ihrem gesamten Frequenzspektrum wiedergeben, was die Klangqualität von Festnetzverbindungen deutlich übertrifft.
 
FRITZ!Fon unterstützt die übertragung großer Bandbreiten. Dies ermöglicht neben HD-Telefonie auch die Nutzung komfortabler Internetdienste wie den Empfang von E-Mails, Podcasts, RSS-Feeds und Internetradio.
 
Die Steuerung von FRITZ!Box-Anwendungen am Handgerät bietet viel zusätzlichen Komfort. Und durch DECT-Eco wird Funkabstrahlung bei Nichtnutzung der Telefone verhindert.
 
Die FRITZ!Box-Modelle FRITZ!Box Fon WLAN 7390, 7320, 7270, 7240 sowie FRITZ!Box 6360 Cable stellen mit der integrierten DECT-Basisstation, mehreren Anrufbeantwortern und Telefonbüchern für bis zu 300 Einträge den idealen Partner für das FRITZ!Fon dar. Mit der umfangreichen Prozessor- und Speicherausstattung ist auch der Grundstein für neue Anwendungen gelegt. Denn das FRITZ!Fon ist lernfähig:
 
Als eines der ersten intelligenten Schnurlostelefone wird es auch künftig per Firmware-Updates aktualisiert und um neue Funktionen erweitert werden können.
 
Umfangreicher Komfort
Das FRITZ!Fon C3 ist mit zahlreichen Komfortfunktionen ausgestattet. Dazu zählen Lauthören und Freisprechen in HD-Qualität sowie ISDN-Leistungsmerkmale wie Namensanzeige bei bekannten Rufnummern, Halten, Makeln, Anklopfen, Rufumleitung oder Dreierkonferenz. Die Internettelefonie in HD-Qualität lässt sich so in ihrem vollen Umfang und Komfort nutzen, ohne dass der Computer eingeschaltet sein muss.
 
FRITZ!Fon informiert zudem aktiv über unbeantwortete Anrufe, Nachrichten auf dem Anrufbeantworter und zeigt eingegangene E-Mails an. An der DECT-Basisstation der FRITZ!Box Fon WLAN 7390, 7320, 7270, 7240 oder FRITZ!Box 6360 Cable lassen sich bis zu 6 FRITZ!Fon-Handgeräte oder andere DECT-Telefone anmelden. Die Erstinstallation und individuelle Einstellungen erfolgen dabei bequem über einfache Assistenten.
 
FRITZ!Box als idealer Partner
Das FRITZ!Fon C3 kann als Mobilteil an jeder DECT-Basisstation eingesetzt werden. Im Zusammenspiel mit der FRITZ!Box Fon WLAN 7390, 7320, 7270, 7240 oder FRITZ!Box 6360 Cable kann jedoch das volle Spektrum der Möglichkeiten beim Telefonieren und Surfen über das Internet ausgenutzt werden.
 
Die FRITZ!Box Fon WLAN 7390 zum Beispiel vereint eine bisher nicht erreichte Vielfalt in einem Gerät: VDSL- und ADSL-Unterstützung, DECT-Basisstation fürs schnurlose Telefonieren sowie WLAN N für die optimale Datenübertragung. über den Mediaserver sind gespeicherte Filme, Musik und Bilder auch bei ausgeschaltetem Computer im gesamten Netzwerk verfügbar. Darüber hinaus kann der Online-Speicher wie eine lokale Festplatte genutzt werden. So wird die FRITZ!Box Fon WLAN 7390 zur idealen Plattform für vernetzte Anwendungen wie IPTV, Video on Demand oder Mediastreaming.
 
Bedienung
- Schnelle Anmeldung: Einschalten, Suchtaste der FRITZ!Box drücken, fertig.
 
- Einfache Bedienung über intuitives Menü.
 
- Telefonbuch komfortabel über FRITZ!Box-Oberfläche einrichten und anzeigen.
 
- In FRITZ!Box integrierte Anrufbeantworter einfach am C3 einrichten und abhören.
 
- Blinkendes Nachrichtensymbol signalisiert eingegangene Anrufe, neue Nachrichten auf dem Anrufbeantworter und neue E-Mails.
 

Telefonieren Sie mit dem Schnurlostelefon C3 in bestechender Qualität über das Internet und nutzen Sie komfortable Webdienste.
 
Highlights
- DECT-Telefon für Internet- und Festnetztelefonie, ideal geeignet für die FRITZ!Box Modelle 7270, 7240, 7390 und 6360 Cable
- Farbdisplay und beleuchtete Tastatur
- Telefonbücher für bis zu 300 Einträge, Online-Telefonbuch verfügbar
- Mehrere Anrufbeantworter mit Menüsteuerung und Fernabfrage
- Full-Duplex-Freisprechen
- Unterstützt HD-Telefonie nach CAT-iq
- Per Software-Update einfach um neue Funktionen erweiterbar
 
Eigenschaften DECT-Telefon
- Mobilteilbreite: 49 mm
- Mobilteilhöhe: 138 mm
- Mobilteiltiefe: 26 mm
- Gewicht Mobilteil inkl. Akku: 133 g
- Feldstärkeanzeige
- Freisprechfunktion
- CAT-iq Standard
- Strahlungsarm
- GAP-fähig
- Reichweite im Freien bis zu 300 m
- Reichweite in Gebäuden bis zu 40 m
 
Telefoneigenschaften
- Anruferanzeige (CLIP)
- Picture-CLIP
- Anruferliste
- Anzeige Datum/Uhrzeit
- Anzeige Gesprächsdauer
- Polyphone Klingeltöne: ja
- Hörerlautstärke einstellbar
- Stummschaltung möglich
- Bis zu 300 Telefonbucheinträge
- Wecker
- Telefontyp: Schnurlostelefon
 
Grundeigenschaften
- Farbe: Silber
 
Lieferumfang
- FRITZ!Fon C3
- AAA-Akkupack
- Ladestation
- Netzteil zum Anschluss an das 230-Volt-Stromnetz
- Gedrucktes deutschsprachiges Handbuch
 

Kompatibel zu:
FRITZ!Box Fon WLAN 7270, FRITZ!Box Fon WLAN 7240, FRITZ!Box Fon WLAN 7320, FRITZ!Box Fon WLAN 7390, FRITZ!Box 6360 Cable
";2;False;0;;;"AVM FRITZ!Fon C3 VoIP Dect-Telefon ";avm-fritzfon-c3-voip-dect-telefon;True;True;P-2750;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;69.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40200,5014467593;20;34;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000537-avm-fritzfon-c3-voip-dect-telefon.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000538-avm-fritzfon-c3-voip-dect-telefon.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000539-avm-fritzfon-c3-voip-dect-telefon.jpg;3;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Canon PIXMA MP560 Multifunktionsgerät 3 in 1;Canon PIXMA MP560 Multifunktionsgerät 3 in 1;"Canon PIXMA MP560 Multifunktionsgerät
 
3 in 1, Drucken, Kopieren, Scannen

Multifunktionssystem: Fotodrucker, Farbscanner und Farbkopierer
Druckgeschwindigkeit: ca. 9,2 (SW) bzw. 6,0 (Farbe) ISO-Seiten/Min; einzelne Tintentanks
ca. 39 Sek. für den druck eines 10 x 15 cm Randlosprint in Laborqualität
Benutzerfreundliches und intuitives Interface; 5 cm Display und Easy-Scroll-Bedienrad
Lieferumfang: PIXMA MP560, Netzkabel, Druckkopf, Tintentanks, Kurzanleitung,CD mit Installations-Software und Benutzerhandbuch, ";2;False;0;;;"Canon PIXMA MP640 ";canon-pixma-mp560-multifunktionsgeraet-3-in-1;True;True;P-2230;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;139.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40194,5747453704;22;25;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000460-canon-pixma-mp560-multifunktionsgerat-3-in-1.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000461-canon-pixma-mp560-multifunktionsgerat-3-in-1.jpg;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Panasonic Lumix DMC-FS7 Digitalkamera schwarz;"Panasonic Lumix DMC-FS7 Digitalkamera schwarz ";"
Panasonic Lumix DMC-FS7 Digitalkamera schwarz

10 Megapixel, 4-fach opt. Zoom, 6,9 cm Display, Bildstabilisator
 
Im Intelligenten Automatik (iA)-Modus werden die 5 wichtigsten Motivprogramme automatisch optimal auf die jeweilige Szene eingestellt.
Neben der Motiverkennung kombiniert iA weitere wichtige Funktionen, wie den optischen Bildstabilisator OIS,
die Bewegungserkennung (Intelligente ISO-Steuerung), eine optimierte Gesichtserkennung mit digitaler Rotaugen-Korrektur. So sind scharfe, natürliche und schöne Fotos selbst für (Neu-)Einsteiger möglich.
 
Lichtstarkes F2,8 Leica DC Vario-Elmarit Objektiv
Hochauflösendes 6,9 cm LC-Display [230.000 Pixel]
4x optischer Zoom [KB: 33-132 mm]
Intelligente Automatik [u.a. Gesichtserkennung]
 
Lieferumfang:
Digitalkamera, Lithium Ionen Akku, Ladegerät, USB-Kabel, Trageriemen, Audio / Video-Kabel, CD-ROM, Sotware
";2;False;0;;;"Panasonic Lumix DMC-FS6 ";panasonic-lumix-dmc-fs7-digitalkamera-schwarz;True;True;P-1780;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;169.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40189,6771412037;58;12;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000453-panasonic-lumix-dmc-fs7-digitalkamera-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000454-panasonic-lumix-dmc-fs7-digitalkamera-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000455-panasonic-lumix-dmc-fs7-digitalkamera-schwarz.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Casio EX-H10 SR Digitalkamera silber;Casio EX-H10 SR Digitalkamera silber;"
Casio EX-H10 SR Digitalkamera silber
 
12 Megapixel, 10-fach opt. Zoom, 7,6 cm  Display, Bildstabilisator
 
Die Kombination aus einem energiesparenden Prozessor und einem extrem leistungsstarken Lithium-Ionen-Akku sorgt dafür, dass der EXILIM EX-H10 auch an langen, erlebnisreichen Tagen nicht der Strom ausgeht und sie mit einer Akkuladung bis zu 1000 Fotos machen kann.
 
12,1 Megapixel CCD-Chip
10fach optischer Zoom mit mechanischem Bildstabilisator, 4fach digitaler Zoom, 24 mm Weitwinkel Objektiv
7,6 cm (3,0 Zoll) TFT-Farbdisplay (Super Clear LCD)
Bis zu 1000 Fotos mit einer Akkuladung
 
Lieferumfang:
Digitalkamera EX-H10 silber, wiederaufladbarer Lithium-Ionen-Akku , Ladegerät, AC-Anschlusskabel, USB-Kabel, AV-Kabel, Trageriemen, CD-ROM
";2;False;0;;;"Casio EX-H10 SR Digitalkamera ";casio-ex-h10-sr-digitalkamera-silber;True;True;P-1760;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;289.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40189,6684375;57;9;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000450-casio-ex-h10-sr-digitalkamera-silber.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000451-casio-ex-h10-sr-digitalkamera-silber.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000452-casio-ex-h10-sr-digitalkamera-silber.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;BenQ G2420HDBL 61 cm 24 Zoll TFT Monitor schwarz;BenQ G2420HDBL 61 cm (24 Zoll) Full-HD LED-Monitor (DVI, VGA, Reaktionszeit 5ms) schwarz;"
BenQ G2420HDBL - Der High-End-Entertainer!
Der G2420HDBL LED-Monitor mit seiner BenQ LED-Edge-Backlight-Technologie im 16:9 Widescreen-Format und einer Bilddiagonale von 61 cm (24 Zoll) verfügt über eine Full-HD-Auflösung (1920 x 1080p), einen dynamischen Kontrast von 5.000.000:1, eine Reaktionszeit von 5 ms sowie eine Helligkeit von 250 cd/m². Zusätzlich sorgt die BenQ Senseye®-Photo-Technologie für eine perfekte Bildqualität bei jeder Anwendung. Mit seinem schwarz glänzenden Design ergänzt dieses PC-Display elegant jedes Büro und jedes Zuhause.
 
Sparen Sie Energie - und Geld!
Aufgrund der stetig zunehmenden globalen Erderwärmung wird es immer wichtiger, CO²-Emissionen zu reduzieren. Die LED Monitore von BenQ haben einen um 36% verringerten Energieverbrauch im Vergleich zu herkömmlichen Monitoren. Im Eco-Modus sparen Sie nochmal 30% der Energie! Und schonen zusätzlich auch noch Ihren Geldbeutel!
 
BenQ Senseye® Human Vision Technology
Mit 6 proprietären Verfahren für die Kalibrierung eines perfekten Bildes.
Dank der Senseye® Technologie und der 6 verschiedenen Techniken zur Farbkalibrierung, zeigen BenQ LED Monitore echte Farben.
 
Comfortable
Die Helligkeit des Monitors lässt sich so fein einstellen, dass Sie ein perfekt ausgeleuchtetes Bild erhalten.
 
Clear
Exakte Ränder und Bilder, die scharf bis ins kleinste Detail sind.
 
Detailed
Detaillierte Bilder dank des hohen dynamischen Kontrasts von 5.000.000:1.
 
Clean
Sämtliche Darstellungen sind frei von Bildrauschen.
 
Brilliant
Klarere Bilder und leuchtend echte Farben lassen die Bilder farbenfroh erscheinen.
 
Balanced
Dank eines integrierten Algorithmus enthält die Bilddarstellung ein ausgewogenes Farbbild.
   
Herausragende LED Farbgestaltung
 
1080p Full-HD (1920x1080 High Definition)
Full-HD-Displays bieten ein breitformatiges Vollbild mit 1080p-Auflösung nach dem HD-Standard (High-Definition). So kann z. B. mit Blu-ray-Playern, Multimedia-PCs, Notebooks oder Spielekonsolen der neuesten Generation das volle Bild digital ohne Kompromisse in brillantester Bildqualität dargestellt werden. Mit dem 16:9-Wide-Format, das perfekt für die Darstellung von Full-HD-Filmen ist, wird zudem bis zu 30 % mehr Bildfläche dargestellt als beim 4:3-Format.
 
Dynamischer Kontrast von 5.000.000:1!
Der extrem hohe dynamische Kontrast von 5.000.000:1 zeigt - insbesondere in dunkleren und komplexen Bewegungsbildern, wie bei Filmen und Video-Spielen - sogar die kleinsten Details in brillanter Schärfe. Sie erhalten fantastische Bilddetails sowie ein klares Bild auch bei dunklen, komplexen und bewegten Bildern. Noch nie haben Sie ein reineres weiß oder ein tieferes schwarz gesehen!
 
16:9 Format - Die 10%, die Ihr visuelles Vergnügen vervollständigen!
Wenn ein traditioneller 16:10 Monitor 16:9 Signale in Full-HD Bilder umwandelt, geschieht dies normalerweise auf zwei Wegen. Die erste Möglichkeit wäre, die Bilder zu strecken, was zu Verzerrungen führt. Eine andere Variante wäre, das überschüssige Bild mit schwarzen Balken zu verdecken. Beide Wege, ob eine Streckung von 10 % oder eineVerdeckung von 10 % des Bildes, haben einen erheblichen Einfluss auf den Bildgenuss.
 
Die BenQ Full-HD 16:9 LED-Monitore hingegen bieten Ihnen eine Punkt-für-Punkt Full-HD Bildübermittlung, um die Probleme der 16:10 Monitore zu lösen. Nun können Sie endlich eine 100 %-ige Full-HD Performance genießen, auf die Sie gewartet haben!
 
Für eine saubere Umwelt
 
Umweltschutz durch Reduzierung des Verpackungsmaterials
Unser Beitrag zum Umweltschutz: 80% des Verpackungsmaterials besteht aus recyceltem Papier, das Verpackungsmaterial insgesamt wird stark reduziert. Dank der schlanken LED-Panels erhöht sich beim Transport der Monitore das freie Ladevolumen um 56% (im Vergleich zur letzten Modellreihe E2400HD). Wir helfen, die Wälder zu schützen und CO2-Emissionen zu reduzieren!
 
Wasserressourcen schützen
Quecksilber-freie LED-Panels reduzieren die Umweltverschmutzung auf der Erde. Da im Produktionsprozess kein Quecksilber verwendet wird und beim Recycling der Altgeräte kein Quecksilber entsorgt werden muss, halten sie die Wasserressourcen frei von giftigen Schadstoffen.
 
Abfallbelastung reduzieren
BenQ LED Monitore sind nicht beschichtet und zu 100% recycelbar. Um die Ressourcen zu schonen, besteht der Displayrahmen zu 28% aus recycelten Plastikmaterialien. Für das Bedrucken des Verpackungsmaterials verwendet BenQ Tinte aus einem natürlichen Rohstoff: der Sojabohne. Damit lässt sich der Tintenverbrauch um 70% reduzieren.
 
";2;False;0;;;BenQ G2420HDBL 61 cm 24 Zoll TFT Monitor schwarz;benq-g2420hdbl-61-cm-24-zoll-tft-monitor-schwarz;True;True;P-2510;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;149.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40187,661724537;"10;2095";;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000443-benq-g2420hdbl-61-cm-24-zoll-tft-monitor-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000444-benq-g2420hdbl-61-cm-24-zoll-tft-monitor-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000445-benq-g2420hdbl-61-cm-24-zoll-tft-monitor-schwarz.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Benq E2220HD 21,5 Zoll TFT Monitor schwarz;Benq E2220HD 21,5 Zoll TFT Monitor schwarz glänzend;"
1080p Full HD (1920x1080 High-Definition)
Im Gegensatz zu konventionellen LCD-Monitoren bieten Full-HD-Displays ein breitformatiges Vollbild mit 1080p-Auflösung nach dem HD-Standard (High-Definition). So kann z. B. mit Blu-ray-Playern, Multimedia-PCs, Notebooks oder Spielekonsolen der neuesten Generation das volle Bild digital ohne Kompromisse in brillantester Bildqualität dargestellt werden. Mit dem 16:9-Wide-Format, das perfekt für die Darstellung von Full-HD-Filmen ist, wird zudem bis zu 30 % mehr Bildfläche dargestellt als beim 4:3-Format.
 
HDMI (High-Definition Multimedia Interface)
Der HDMI-Anschluss ist eine digitale Schnittstelle, die für den Videobereich entwickelt wurde und neben dem Bild auch den Ton überträgt. HDMI ermöglicht nicht nur Datentransfers von 5 GB/s, sondern verhindert auch Wandlungsverluste und sorgt so für eine ausgezeichnete Bildqualität. Die HDMI-Schnittstelle ist der neue Standard für die digitale Signalübertragung, unter anderem für DVD-Player oder Spielkonsolen. Ab dem Standard HDMI 1.3 sind Übertragungsraten von bis zu 10 GB/s (je nach Kabelqualität und -länge) möglich. Dadurch werden die großen Datenströme ohne Kompressionen und damit ohne Bildstörungen übertragen. Dies ist für die Abbildung von Full-HD (1080p) wichtig, um einen ruckelfreien Bildfluss zu gewährleisten. Das BenQ E2220HD Display verfügt über 2 HDMI 1.3-Schnittstellen.
 
Vier USB-Schnittstellen
Das E2220HD verfügt über gleich vier USB-Schnittstellen, so dass Sie gleichzeitig Ihre Tastatur, die Maus, ein Handy und z.B. Game-Controller anschließen können!
 
Dynamischer Kontrast von 50.000:1
Mit einem dynamischen Kontrast von 50.000:1 werden Ihre Bilder lebendiger! Sie erhalten fantastische Bilddetails sowie ein klares Bild auch bei dunklen, komplexen und bewegten Bildern. Um die Funktion zu steuern, schalten Sie einfach den Q-Pilot ein.
 
Stereo-Lautsprecher
Das E2220HD verfügt über 2 1,5 Watt Stereo-Lautsprecher, die Ihnen ein perfektes Klangerlebnis liefern.
";2;False;0;;;Benq E2220HD 21,5 Zoll TFT Monitor schwarz;benq-e2220hd-215-zoll-tft-monitor-schwarz;True;True;P-2500;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;199.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40187,6466435185;10;;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000438-benq-e2220hd-215-zoll-tft-monitor-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000439-benq-e2220hd-215-zoll-tft-monitor-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000440-benq-e2220hd-215-zoll-tft-monitor-schwarz.jpg;1;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Apple iPod Touch 32 GB schwarz;Apple iPod Touch 32 GB schwarz;"
Apple iPod Touch 32 GB schwarz
 
mit integrierter WiFi Funktion
 
Ein großartiger iPod. Ein großartiger Taschencomputer. Großartiger mobiler Spielspaß. Und das Ganze in einem unglaublich schlanken, eleganten neuen Design aus Edelstahl. Filme, Videos und Fernsehsendungen auf einem 3,5"" Display ansehen!
 
Im Web surfen, mailen!
Multitouch-Oberfläche: Die revolutionäre Technologie des iPhone und die Software Version 3.1 stecken in diesem genialen iPod. Das brillante Breitformat-Display rückt Ihre Videos und Spiele ins beste Licht
 
Surfen Sie mit Safari im Web und sehen Sie YouTube Videos auf dem iPod mit integrierter Wi-Fi Funktionalität an.
Mit Ihrem iPod touch können Sie im iTunes Wi-Fi Music Store nach Songs suchen, Hörproben abspielen und Titel kaufen.  Lieferumfang: iPod touch, Ohrhörer, USB 2.0 Kabel, Dock-Adapter, Kurzanleitung
 
Der iPod touch kann alles, was du am iPod toll findest. Und noch vielmehr.
Du kannst Filme, Videos und Fernsehsendungen auf einem 3,5"" Display ansehen. Mit der revolutionären Multi-Touch-Technologie kannst du dein Musikarchiv mit Cover Flow durchblättern. Und wenn dir nach mehr ist, tipp einfach auf iTunes, um durch das Angebot zu stöbern und sofort einzukaufen. Hör dir Wiedergabelisten an, die automatisch für dich erstellt werden. Schau Filme auf dem brillanten 3,5"" Display. Und kauf mit einem Fingertipp bei iTunes ein - wann immer du willst. All das und noch viel mehr mit dem iPod touch, den es schon ab 189 € gibt. Wi-Fi ist schon integriert. So kannst du im Web surfen, mailen, deinen Facebook Status aktualisieren, mit AIM chatten und noch viel mehr - und das alles auf einem Gerät, das locker in jede Tasche passt. Hier hast du die Finger im Spiel. Und nicht nur die. Denn mit den Spielen auf dem iPod touch tauchst du richtig in die Action ein - einfach neigen, tippen, drehen. Und via Wi-Fi kannst du jederzeit im App Store neue Spiele kaufen. Die iPhone 3.1 Software ist auf dem iPod touch bereits installiert, sodass der Spaß gleich beginnen kann. Damit kannst du nützliche Funktionen wie Peer-to-Peer-Spiele und Cut, Copy & Paste direkt nach dem Auspacken nutzen.
Next Level Fun: Der neue iPod touch
 
Musik
Stöber durch deine Alben. Hör dir einen einzigartigen Mix an, der nur für dich erstellt wurde. Oder schau das Video deines Lieblingssongs an. Mit dem iPod touch kannst du mehr als nur Musik hören.
 
Cover Flow
Auf dem iPod touch gibt's Musik nicht nur auf die Ohren. Mit Cover Flow ist Musik auch etwas für Augen und Finger. Dreh den iPod touch einfach auf die Seite und blätter durch deine Albumcover. Tipp auf ein Albumcover, um es umzudrehen und die Songliste zu sehen. Tipp noch einmal und Musik ab.
 
Genius Mixe
Die Genius Funktion wurde weiter verbessert. Jetzt gibt es Genius Mixe. Du brauchst den iPod touch nur mit iTunes zu synchronisieren. Genius durchsucht dann automatisch deine Mediathek nach Songs, die gut zusammenpassen und erstellt bis zu zwölf Mixe.
Diese Mixe sind wie Radiosender, auf denen nur deine Musik läuft.
 
Genius Wiedergabelisten
Angenommen du hörst einen Song auf deinem iPod touch, der dir gut gefällt, und du möchtest weitere Titel hören, die dazu passen. Genius findet weitere Songs auf deinem iPod touch und erstellt eine Genius Wiedergabeliste für dich. Hör dir die Wiedergabeliste sofort an, speichere sie für später oder versuch's noch einmal und sieh, was dabei herauskommt. Verlass dich auf Genius, wenn du einen Mix willst, auf den du selbst nie gekommen wärst.
 
Shake to Shuffle
Die Dinge mal aufrütteln. Musikalisch natürlich. Wenn du das nächste Mal Musik hörst, aktiviere die Schüttelfunktion und wenn du den iPod touch dann kurz schüttelst, springt er nach dem Zufallsprinzip zu einem anderen Song aus deiner Sammlung.
 
iTunes
Pack Musik und Videos aus der iTunes Mediathek deines Computers auf den iPod touch. Oder kauf und lade neue Songs auf den iPod touch, wenn du über Wi-Fi auf iTunes zugreifst. Wenn du den iPod touch das nächste Mal mit dem Computer verbindest, werden alle Songs, die du auf dem iPod touch gekauft hast, auf den Mac oder PC übertragen.
 
Bluetooth
Schau mal, keine Kabel. Der iPod touch enthält die iPhone 3.1 Software, sodass du Bluetooth Stereokopfhörer anschließen kannst. Lass den iPod in deiner Tasche stecken oder auf dem Schreibtisch aufladen, während du weiter Musik hörst.
 
Filme und Fernsehsendungen
Ein Kinohit. Ein Video-Podcast. Deine Lieblingsserie. Jetzt laufen sie auch in einer U-Bahn oder einem Flugzeug in deiner Nähe.
Widescreen-Display
Du kannst Videos für viele Stunden überallhin mitnehmen und auf dem gestochen scharfen 3,5"" Widescreen-Farbdisplay ansehen. Kauf im iTunes Store und wähle unter tausenden vonFilmen, Fernsehsendungen und Video-Podcasts, die du auf den iPod touch laden kannst. Von Hollywood-Hits bis zu Indie-Streifen - es gibt etwas für jeden Geschmack. Mit wenigen Fingertipps kannst du Filme kaufen und laden. Du magst lieber Fernsehsendungen? Lade eine einzelne Folge oder die gesamte Staffel.
 
On-Screen Steuerung
Auch während du Video guckst, kannst du die Steuerung einblenden - ein Fingertipp auf das Display genügt. Du kannst die Wiedergabe starten oder unterbrechen, einzelne Kapitel anzeigen und die Lautstärke anpassen. Natürlich kannst du auch die Lautstärkeregler links am iPod touch verwenden. Du willst zwischen Widescreen und bildschirmfüllender Anzeige wechseln? Einfach aufs Display doppeltippen.
 
iTunes
Du brauchst Unterhaltung für deinen nächsten Flug oder die Autofahrt? Mit iTunes auf dem iPod touch und einer Wi-Fi-Verbindung kannst du auch unterwegsFilme und Fernsehsendungen kaufen. Du kannst Filme auch leihen, wenn du dir nicht sicher bist, ob du den Film behalten willst. Und natürlich kannst du Filme und Fernsehsendungen auf dem Mac oder PC kaufen und dann mit dem iPod touch synchronisieren.
 
App Store
Kaufe im App Store und entdecke über 65.000 Apps, mit denen du noch mehr auf dem iPod touch machen kannst. Stöbere in tausenden von Apps in verschiedenen Kategorien. Von Spielen über Lifestyle und Soziale Netzwerke bis zu Unterhaltung und mehr.
 
Apps durchstöbern
Du kannst auf verschiedene Arten im App Store shoppen. Tipp auf ""Neu"" und ""Topaktuell"", um eine Liste der aktuellen und angesagten Apps zu erhalten. Stöbere nach Kategorien. Schau dir die topaktuellen Apps an. Wenn du genau weißt, wonach du suchst, kannst du auch eine Schnellsuche durchführen.
 
Genius Empfehlungen für Apps
Es gibt tausende von Apps im App Store, und jeden Tag kommen mehr dazu. Mit dieser neuen Funktion des iPod touch findest du coole neue Apps noch einfacher. Genius für Apps. Funktioniert genau wie Genius für deine Musik. Tipp auf das Genius Symbol und du bekommst Empfehlungen für Apps anhand der Apps, die du und andere schon geladen haben.
 
Apps laden
Wenn du eine App findest, die dich interessiert, kannst du sie überall, wo eine Wi-Fi-Verbindung besteht, drahtlos kaufen, auf den iPod laden und dann sofort loslegen.
 
Updates für Apps
iPod touch sagt dir, wenn ein App Update verfügbar ist, damit du immer die neuesten Versionen deiner Lieblings-Apps hast.
 
iTunes
Entdecke und lade neue Musik, Filme, Fernsehsendungen, Podcasts und Hörbücher in iTunes auf dem iPod touch.
 
Einkaufen, immer und überall
Greif über die im iPod touch integrierte Wi-Fi-Funktion auf den iTunes Store zu. Durchsuche Millionen von iTunes Plus Songs in brillanter Audioqualitätund tausende von Filmen, Fernsehsendungen, Hörbüchern und kostenlosen Podcasts und Vorlesungen von iTunes U. Stöbere nach Neuerscheinungen, Top-Titeln und Genres. Oder finde mit der Schnellsuche genau das, wonach du suchst. Hör in einen Song oder sieh dir eine Videovorschau an. Wenn du dann etwas kaufen möchtest, brauchst du nur darauf zu tippen. Nicht sicher, ob es sich lohnt, den Film zu kaufen? Dann leih ihn einfach. Alles was du auf dem iPod touch kaufst, hat denselben Preis wie im iTunes Store auf deinem Computer.
 
Synchronisieren mit iTunes
Sobald du den iPod touch mit dem Computer verbindest, werden die Songs, Filme, Fernsehsendungen, Hörbücher und Podcasts, die du unterwegs geladen hast, mit deiner iTunes Mediathek auf deinem Mac oder PC synchronisiert. Wenn du etwas nur teilweise auf den iPod touch geladen hast, beendet der Computer den Download automatisch für dich.
 
Sprachsteuerung
Mit der Sprachsteuerung beim neuen 32 GB und 64 GB iPod touch kannst du deine Musik mit Sprachbefehlen steuern. Und der iPod hört aufs Wort. Auf ""Spiel"", ""Shuffle"" oder ""Wie heißt das Lied?"".
 
Sagen und abspielen.
Die Sprachsteuerung kennt die Musik auf deinem iPod touch. Wenn du etwas Bestimmtes hören willst, sag es einfach. Zum Beispiel ""Spiel Bob Dylan"" und der iPod touch hört aufs Wort. Frag ihn, welcher Song grad läuft, und der iPod touch sagt es dir. Sag ihm, dass er dein Lieblingsalbum, deinen Lieblingssänger oder deine Lieblingswiedergabeliste spielen soll. Verwende einfache Befehle wie ""shuffle"", ""nächster Song"" und ""anhalten"". Du kannst dem iPod touch sogar sagen, dass er mehr Songs wie den, der gerade läuft, abspielen soll.
 
Sprich ins Mikro
Der neue 32 GB und 64 GB iPod touch wird mit den Apple Earphones mit Fernbedienung und Mikro geliefert. So kannst du die Sprachsteuerung auch dann nutzen, wenn der iPod touch in der Tasche steckt. Zum Aktivieren der Sprachsteuerung über die Kopfhörer hältst du einfach die Mitteltaste der Fernbedienung gedrückt.
 
Die Sprachsteuerung unterstützt die folgenden Sprachen:
Chinesisch (China), Chinesisch (Kantonesisch), Chinesisch (Taiwan), Deutsch, Englisch (Großbritannien), Englisch (USA), Finnisch, Französisch (Frankreich), Französisch (Kanada), Italienisch, Japanisch, Koreanisch, Niederländisch, Norwegisch, Polnisch, Portugiesisch (Brasilien), Portugiesisch (Portugal), Russisch, Schwedisch, Spanisch (Mexiko), Spanisch (Spanien)
 
Fotos
Der iPod touch hat für bis zu 90.000 deiner Lieblingsfotos Platz. Durch Streichen kannst du sie durchschauen und all die Erinnerst-du-dich-noch-Momente mit anderen teilen.
 
Fotos sichern
Wenn dir tolle Bilder gemailt werden, kannst du sie einfach im Fotoarchiv auf dem iPod touch sichern und dann wie jedes andere Foto nutzen. Du kannst sie zum Beispiel als Hintergrundbilder verwenden, im Internet teilen oder weitergeben.
 
Fotos teilen
Du hast tausende Fotos immer zur Hand. Blätter durch Streichen auf dem Display durch Miniaturen. Mit einem Fingertipp siehst du Fotos bildschirmfüllend. Spiel Diashows mit Musik und Übergängen ab. Maile Fotos an Freunde oder teile sie in einer MobileMe Galerie.
 
Fotos synchronisieren
Fotos aus iPhoto auf einem Mac oder Adobe Photoshop Elements und Adobe Photoshop Album auf einem PC werden via iTunes mit dem iPod touch synchronisiert. Einfach nur die Fotos und Alben aussuchen, die mit dem iPod touch synchronisiert werden sollen. Dann kannst du sie überall ansehen und mit anderen teilen.
 
Homescreen
Angenommen du möchtest ""Karten"" als erste App in der zweiten Zeile haben. Oder Mail unten im Dock. Mit den anpassbaren Homescreens kannst du den iPod touch zu deinem iPod touch machen.
 
Individuelles Anpassen
Ordne die Symbole auf deinem Homescreen an wie du willst - direkt auf dem iPod touch oder auf deinem Computer in iTunes 9. Bewege eine App eine Zeile nach oben, zwei Apps nach rechts oder auf einen anderen Homescreen. Du kannst bis zu 11 Homescreens erstellen und hast so schnellen Zugriff auf Spiele und Apps, die du aus dem App Store lädst, und auf deine Safari Weblinks.
 
Hometaste
Was auch immer du gerade mit deinem iPod touch machst – die Hometaste bringt dich immer zurück zum ersten Homescreen. Wenn du auf die Hometaste drückst, kannst du von jedem Homescreen wieder zurück zum ersten springen.
 
Apps und Weblinks hinzufügen
Für jede App, die du aus dem App Store lädst, erscheint ein neues Symbol auf dem Homescreen. Von häufig besuchten Websites kannst du praktische Weblinks erstellen. Sie erscheinen auf dem Homescreen und du kannst per Fingertipp darauf zugreifen.
 
Spotlight Suche
Du suchst was? Von einem Ort aus kannst du die gesamten Inhalte des iPod touch durchsuchen. Streich auf dem ersten Homescreen einfach nach rechts, um Spotlight zu öffnen. Sobald du anfängst zu tippen, durchsucht Spotlight deine gesamten Songs, Videos, Kontakte, Mails, Kalender, Notizen und sogar deine Hörbücher und Podcasts.
 
Safari
Safari, der fortschrittlichste Webbrowser auf einem Mobilgerät, ist auch auf dem iPod touch integriert. Damit erlebst du das Internet in deiner Hand genauso wie auf dem Computer zuhause. Alles was du brauchst ist eine Wi-Fi-Verbindung.
 
Überall ins Internet
Der iPod touch ist der einzige iPod mit integriertem drahtlosen Internetzugriff. Bei bestehender Wi-Fi-Verbindung kannst du im Internet surfen und Nachrichten lesen, Sportergebnisse sehen, Rechnungen bezahlen und online einkaufen. Und beim 32 GB oder 64 GB iPod touch wirst du sehen, dass Webseiten jetzt noch schneller als vorher geladen werden.
 
Im Web stöbern
Der iPod touch synchronisiert deine Lesezeichen vom PC oder Mac, sodass du ruckzuck auf deine Lieblingsseiten zugreifen kannst. Außerdem ist die Google- und Yahoo!-Suche schon integriert, sodass du im Web schnell findest, was du suchst.
 
Weblinks
Wenn du eine Website öfter besuchst - etwa die einer Zeitung, eines Blogs oder eine Sport-Website - kannst du einfach ein Symbol, einen sogenannten Weblink, auf dem Homescreen erstellen. Wenn du mit Safari Weblinks erstellst, sind deine Lieblingsseiten nur einen Fingertipp entfernt.
 
Zoom
Wenn du eine Website öfter besuchst, brauchst du nur mit dem Finger auf das Multi-Touch-Display zu tippen oder die Anzeige aufzuziehen. Websites lassen sich im Hoch- oder Querformat anzeigen. Einfach den iPod touch um 90 Grad drehen, und schon wird auch die Darstellung der Webseite gedreht.
 
Mail
Mails auf dem iPod touch funktionieren genau wie auf deinem Computer und sehen auch genau so aus. Und sie funktionieren mit deinen vorhandenen Accounts.
 
Nachrichten und Anhänge ansehen
Der iPod touch unterstützt Rich-HTML-E-Mail, sodass Bilder und Fotos zusammen mit dem Text einer E-Mail angezeigt werden. Anhänge siehst du in ihrem Originalformat und nicht als abgespeckte Version. Du kannst in mehr als einem Dutzend standardmäßigen Datei- und Bildformaten drehen, zoomen und schwenken, darunter PDF, Microsoft Word, Excel, PowerPoint und iWork.
 
Zugriff auf alle Accounts
Mails von gängigen Anbietern wie MobileMe, Google Mail, Microsoft Exchange, Yahoo! und den meisten standardmäßigen IMAP- und POP-Systemen kannst du mit dem iPod touch ganz einfach abrufen.
 
Schnellere Eingabe
Der iPod touch erkennt E-Mail-Adressen in verschiedenen Programmen. Wenn du auf einer Webseite oder in einer Karte eine E-Mail-Adresse siehst, reicht ein Fingertipp auf dem iPod touch, um eine neue Mail zu öffnen, in der die Adresse bereits eingetragen ist.
 
Intelligente Eingabe
Die innovative iPod touch Tastatur mit integriertem Wörterbuch* schlägt während der Eingabe Wörter vor. So kannst du ganz schnell und einfach Mails schreiben. Dreh den iPod touch einfach. Dann wird die Tastatur vom Hochformat ins Querformat gedreht und du hast größere Tasten und mehr Platz zum Tippen.
 
Postfach durchsuchen
Du musst das Postfach jetzt nicht mehr Mail für Mail durchsuchen. Durch schnelles Abwärtsstreichen wird jetzt ein Suchfeld geöffnet, mit dem du deine Mails nach Absender, Empfänger, Betreff oder Titelzeilen durchsuchen kannst.
 
Karten
Finde deinen Weg und die nächste Pizzeria. Mit Karten und einer Wi-Fi-Verbindung kannst du Wegbeschreibungen abrufen, Firmen finden und Verkehrsinformationen prüfen.
 
Finde dich selbst
Der iPod touch zeigt dir mithilfe von bekannten Wi-Fi-Hot-Spots, wo du bist. Mit der Stichwortsuche kannst du auch interessante Orte finden. Wenn du z. B. ""Kaffee"" eingibst, werden dir alle Cafés in der Nähe angezeigt.
 
Wo geht's lang?
Gib einfach eine Adresse ein, um Wegbeschreibungen abzurufen - von jedem Ort aus. Wähle das Transportmittel wie Auto, öffentliches Verkehrsmittel oder zu Fuß. Die Route lässt sich dann Schritt für Schritt anzeigen. Du kannst dem markierten Weg auf der Karte folgen und selbst die Fahrtdauer wird angezeigt. Oder markiere zwei Orte und lass dir die beste Route zwischen diesen anzeigen.
 
Verschiedene Kartendarstellungen
Wie bei Google Karten auf deinem Computer kannst du mit dem Programm ""Karten"" auf dem iPod touch zwischen unterschiedlichen Darstellungen von Google-Karten, Satellitenbildern und einer Hybriddarstellung wechseln. Und mit Multi-Touch kannst du unterwegs zoomen, den Ausschnitt bewegen und die Darstellung ändern.
 
Verkehrsinformationen
Die Verkehrsinformationen geben dir anhand der grünen, roten und gelben Markierungen einen Überblick über die Verkehrssituation auf deiner Route.
 
YouTube
Skateboard Moves, die so nicht geplant waren. Witzige Werbespots aus anderen Ländern. Was auch immer du gern auf YouTube ansiehst - der iPod touch ist für dich da.
 
Videogrüße von unterwegs.
Maile Links deiner Lieblingsvideos an Freunde. Tippe auf der Detailseite des YouTube Videos auf ""Senden"", und schon erstellt der iPod touch eine Mail mit dem zugehörigen Videolink.
 
Auf YouTube suchen.
Stöber in Videokategorien wie ""Highlights"", ""Topvideos"", ""Neue Videos"" oder ""Bestwertung"". Du kannst auch per Schlagwort nach einem Video suchen. Etwas Passendes gefunden? Mit einem Lesezeichen kannst du das Video auch vormerken und später ansehen.
 
Nike + iPod Kompatibilität
Rock dein Training. Der iPod touch hat eine integrierte Unterstützung für Nike + iPod. Das ist Musik und Motivation in einem.
Finetuning für dein Lauftraining.
 
Nike + iPod Sensor
Der iPod touch hat eine integrierte Unterstützung für Nike + iPod. Einfach den Nike + iPod Sensor (separat erhältlich) in die Nike+ Schuhe stecken und los geht's. Der Sensor überträgt deine Laufdaten drahtlos an den iPod touch und zeichnet Laufzeit, Laufstrecke und Kalorienverbrauch auf. Du erhältst sogar Feedback zum Trainingsfortschritt.
 
Finetuning für dein Cardio Workout
Diese Funktion kann auch zusammen mit neuen, in vielen Fitnessstudios vorhandenen Geräten für das Ausdauertraining gekoppelt werden. Such dir einfach ein mit Nike + iPod kompatibles Fitnessgerät wie beispielsweise Laufbänder, Ellipsentrainer, Stepper und Hometrainer.
 
Synchronisieren mit nikeplus.com
Später kannst du am Computer den iPod touch via iTunes synchronisieren und deine Trainingsdaten an nikeplus.com übertragen. Auf dieser Website kannst du dein Training verfolgen, dir Ziele setzen und deine Freunde herausfordern.
 
Sprachmemos
Du hast vielleicht ein ganz gutes Gedächtnis, aber manchmal ist es besser, kleine (und große) Infos einfach irgendwo festzuhalten. Mit ""Sprachmemos"" kein Problem.
 
Memos (oder alles andere)aufnehmen
Nimm eine Aufgabenliste, geniale Ideen oder eine Wette zwischen dir und deinem Freund auf. Mit dem Programm ""Sprachmemos"" kannst du über die Apple Earphones mit Fernbedienung und Mikro oder ein externes Mikrofon aufnehmen, was immer du willst. Sprachmemos kannst du selbst dann aufnehmen, wenn du den iPod touch gerade verwendest, um Mails zu checken oder im Web zu surfen.
 
Memos bearbeiten
Aufgenommene Memos kannst du direkt auf dem iPod touch trimmen. So behältst du nur das, was du wirklich brauchst.
 
Memos sortieren
Ordne deine Memos mithilfe von Etiketten aus einer vordefinierten Liste oder erstelle eigene Etiketten.
 
Memos teilen
Maile Memos an Freunde und Kollegen. Mit dem iPod touch aufgenommene Memos werden via iTunes mit deinem Mac oder PC synchronisiert, damit du sie später mit anderen teilen kannst.
 
Weitere Funktionen
Auf dem iPod touch ist die neueste Software schon installiert. Und außerdem gibt's praktische Apps wie Kontakte, Kalender, Notizen, Aktien und Wetter.
 
iPod touch 3.1 Softwarefunktionen.
 
Genius Mixe
Diese neue Funktion ist wie ein privater DJ, der deine iTunes Mediathek durchsucht, um Songs zu finden, die gut zusammenpassen und aus diesen dann tolle Mixe erstellt. Alles ganz automatisch.
 
Genius Empfehlungen für Apps
Im App Store gibt's zehntausende Apps. Wie soll man da die richtig collen neuen finden? Mit Genius. Denn Genius sieht sich die Apps an, die du schon hast, und empfiehlt dir weitere.
 
Peer-to-Peer-Spiele
Die neusten Spiele kannst du ganz leicht mit Freunden spielen - egal, ob sie neben dir oder in einer anderen Ecke des Landes sitzen.
 
Kauf Filme, Fernsehsendungen und Hörbücher via Wi-Fi
Lade via Wi-Fi Filme, Fernsehsendungen, Musikvideos und Hörbücher aus dem iTunes Store auf deinen iPod touch.
 
Tastatur im Querformat
Du brauchst mehr Platz zum Tippen? Dreh den iPod touch ins Querformat, um in Mail, Notizen und Safari mit einer größeren Tastatur zu arbeiten.
 
Cut, Copy & Paste
Einfach Text und Fotos ausschneiden, kopieren und wieder einsetzen - selbst zwischen Programmen. Du kannst auch Inhalte aus dem Web kopieren.
 
Spotlight Suche
Gesucht, gefunden - von einem Ort aus. Spotlight durchsucht alle deine Kontakte, E-Mails, Kalender und Notizen und auch alle Songs und Videos.
 
Stereo Bluetooth
Hör Musik und andere Audioinhalte drahtlos. Verbinde den iPod touch mit kompatiblen Bluetooth Stereokopfhörern.
 
Automatischer Wi-Fi-Login
Wenn du dich einmal bei einem Wi-Fi-Hotspot anmeldest, loggt der iPod touch sich beim nächsten Mal automatisch ein.
 
Shake to Shuffle
Schüttel den iPod kurz, und schon springt er nach dem Zufallsprinzip zu einem anderen Song in deiner Sammlung. Lass dich einfach überraschen.
 
Bedienungshilfen
Der neue iPod touch hat standardmäßig Bedienungshilfen integriert, mit denen auch Menschen mit Beeinträchtigungen alles, was der iPod touch zu bieten hat, erleben können. Alle Bedienungshilfen des iPod touch ansehen
 
Kindersicherung
Du entscheidest, welche Musik, Videos und Apps auf dem iPod touch für deine Kinder geeignet sind.
Der iPod touch hat auch die folgenden praktischen Apps:
 
Kalender
Das Programm ""Kalender"" funktioniert mit Yahoo!, Google, Microsoft Outlook, iCal, MobileMe und Microsoft Exchange ActiveSync für Unternehmen. Füge Termine hinzu, lass dich an Termine erinnern, und abonniere Kalender, damit du über Feiertage und Sportveranstaltungen auf dem Laufenden bleibst.
 
Kontakte
Namen, E-Mail-Adressen, Telefonnummern und mehr - immer zur Hand. Synchronisier Kontakte in iTunes auf dem Mac oder PC mit dem iPod touch. Neue Kontakte kannst du auch unterwegs mit einem einfachen Fingertipp hinzufügen.
 
Notizen
Schluss mit Papier und Bleistift. Mach dir mit ""Notizen"" auf dem iPod schnell eine Notiz, damit du wichtige Infos immer parat hast. Maile deine Gedanken mit der integrierten Mail-Funktion an dich oder andere.
 
Aktien
Die Aktien App auf dem iPod touch zeigt dir Börseninformationen für die Aktien, die dich interessieren. Wenn du nähere Details über eine Aktie brauchst, tipp auf ""Y!"", um im Handumdrehen Yahoo! Finance zu öffnen.
 
Wetter
Informier dich über das Wetter in der ganzen Welt oder zuhause. Füge die gewünschten Städte hinzu und zeige eine sechstägige Vorhersage für alle an. Tipp auf ""Y!"", um den Yahoo! Stadtführer zu öffnen, der dir zeigt, wo was los ist.
 
Rechner
Im Programm ""Rechner"" des iPod touch stecken gleich zwei Rechner. Im Hochformat kannst du ihn als einfachen Taschenrechner verwenden. Dreh den iPod touch ins Querformat, um aus ihm einen wissenschaftlichen Rechner zu machen.
 
iPod touch Technologie
Dank der revolutionären Hardwaretechnologie im iPod touch kannst du alle Funktionen mit Streichen, Tippen und Auf- oder Zuziehen steuern. Deswegen wirkt das Autorennen so echt. Deswegen kannst du das, was du eben im Café mitbekommen hast, sofort twittern. Und genau deswegen ist der iPod touch der beste iPod aller Zeiten.
 
Multi-Touch
Das Multi-Touch-Display besitzt einen Schutzfilm über der kapazitiven Sensorik, die Berührungen anhand elektrischer Felder erkennt. Diese Informationen werden an das darunterliegende LCD-Display übertragen. Dank der Software des iPod touch kannst du mit Cover Flow durch Alben stöbern, durch deine Fotos blättern, mit Auf- und Zuziehen Bildausschnitte von Websites zoomen und Spiele superpräzise steuern.
 
Beschleunigungssensor
Der iPod touch reagiert über einen integrierten Beschleunigungssensor auf Bewegungen. Dieser Sensor erkennt, wenn du deinen iPod touch ins Querformat drehst und verändert automatisch den Inhalt des Displays. Die Technologie des Beschleunigungssensors kommt besonders bei Spielen gut, denn damit bist du mitten im Spielgeschehen. Das ist perfekt für Autorennen, bei denen der ganze iPod zum Lenkrad wird, und Geschicklichkeitsspiele wie Rolando, bei denen du das Spiel mit deinen Bewegungen steuerst
 
Drahtlos
Der iPod touch hat eine integrierte Unterstützung für drahtlosen 802.11b/g Internetzugriff. Überall, wo es ein Wi-Fi-Netzwerk gibt, kommst du mit deinem iPod touch ins Internet. Im Café mailen. Am Flughafen im Web surfen. Spiele vom Sofa aus kaufen. Im iTunes Store stöbern und Musik kaufen und laden. Der iPod touch findet nahegelegene Wi-Fi-Hot-Spots, auch geschützte Netzwerke. Wenn du ein bestimmtes Netzwerk bisher noch nicht verwendet hast, Drahtlos Symbol musst du beim ersten Mal ein Kennwort eingeben, das sich der iPod touch dann merkt. Wenn du dann das nächste Mal in Reichweite dieses Netzwerks bist, loggt er sich automatisch ein.
 
Bluetooth
Bluetooth ist eine drahtlose Technologie, mit der du Geräte ohne lästige Kabel verwenden kannst. Was bedeutet das für den iPod touch? Du kannst jetzt mit dem iPod touch und Bluetooth Kopfhörern Musik hören, ganz egal, wo im Raum der iPod ist. Du kannst also auf dem Bett relaxen, während der iPod auf dem Schreibtisch aufgeladen wird. Bluetooth auf dem iPod touch eignet sich auch besonders für Peer-to-Peer-Spiele.
 
Design
Der iPod touch ist von außen genau so großartig wie von innen. Du brauchst nur einen in die Hand zu nehmen. Das Gehäuse des iPod touch ist gerade einmal 8,5 mm hoch. Das optische Glas auf der Vorderseite und die Rückseite aus poliertem Edelstahl geben ihm einen eleganten Touch und fühlen sich in der Hand einfach gut an. Schalte ihn ein und du wirst über das brillante 3,5"" Display einfach staunen. Der iPod touch ist die perfekte Kombination aus großartigem Design und revolutionärer Technologie - das perfekte Paket.
";2;False;0;;;Apple iPod Touch schwarz mit integrierter WiFi Funktion;apple-ipod-touch-32-gb-schwarz-2;True;True;P-1290;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;269.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40186,8623263889;44;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000434-apple-ipod-touch-64-gb-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000435-apple-ipod-touch-64-gb-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000436-apple-ipod-touch-64-gb-schwarz.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Apple iPod Touch 64 GB schwarz;Apple iPod Touch 64 GB schwarz;"
Apple iPod Touch 64 GB schwarz
mit integrierter WiFi Funktion


Ein großartiger iPod. Ein großartiger Taschencomputer. Großartiger mobiler Spielspaß. Und das Ganze in einem unglaublich schlanken, eleganten neuen Design aus Edelstahl. Filme, Videos und Fernsehsendungen auf einem 3,5"" Display ansehen!
Im Web surfen, mailen!
Multitouch-Oberfläche: Die revolutionäre Technologie des iPhone und die Software Version 3.1 stecken in diesem genialen iPod. Das brillante Breitformat-Display rückt Ihre Videos und Spiele ins beste Licht
Surfen Sie mit Safari im Web und sehen Sie YouTube Videos auf dem iPod mit integrierter Wi-Fi Funktionalität an.
Mit Ihrem iPod touch können Sie im iTunes Wi-Fi Music Store nach Songs suchen, Hörproben abspielen und Titel kaufen. Lieferumfang: iPod touch, Ohrhörer, USB 2.0 Kabel, Dock-Adapter, Kurzanleitung
 
Der iPod touch kann alles, was du am iPod toll findest. Und noch vielmehr.
Du kannst Filme, Videos und Fernsehsendungen auf einem 3,5"" Display ansehen. Mit der revolutionären Multi-Touch-Technologie kannst du dein Musikarchiv mit Cover Flow durchblättern. Und wenn dir nach mehr ist, tipp einfach auf iTunes, um durch das Angebot zu stöbern und sofort einzukaufen. Hör dir Wiedergabelisten an, die automatisch für dich erstellt werden. Schau Filme auf dem brillanten 3,5"" Display. Und kauf mit einem Fingertipp bei iTunes ein - wann immer du willst. All das und noch viel mehr mit dem iPod touch, den es schon ab 189 € gibt. Wi-Fi ist schon integriert. So kannst du im Web surfen, mailen, deinen Facebook Status aktualisieren, mit AIM chatten und noch viel mehr - und das alles auf einem Gerät, das locker in jede Tasche passt. Hier hast du die Finger im Spiel. Und nicht nur die. Denn mit den Spielen auf dem iPod touch tauchst du richtig in die Action ein - einfach neigen, tippen, drehen. Und via Wi-Fi kannst du jederzeit im App Store neue Spiele kaufen. Die iPhone 3.1 Software ist auf dem iPod touch bereits installiert, sodass der Spaß gleich beginnen kann. Damit kannst du nützliche Funktionen wie Peer-to-Peer-Spiele und Cut, Copy & Paste direkt nach dem Auspacken nutzen.
Next Level Fun: Der neue iPod touch
 
Musik
Stöber durch deine Alben. Hör dir einen einzigartigen Mix an, der nur für dich erstellt wurde. Oder schau das Video deines Lieblingssongs an. Mit dem iPod touch kannst du mehr als nur Musik hören.
 
Cover Flow
Auf dem iPod touch gibt's Musik nicht nur auf die Ohren. Mit Cover Flow ist Musik auch etwas für Augen und Finger. Dreh den iPod touch einfach auf die Seite und blätter durch deine Albumcover. Tipp auf ein Albumcover, um es umzudrehen und die Songliste zu sehen. Tipp noch einmal und Musik ab.
 
Genius Mixe
Die Genius Funktion wurde weiter verbessert. Jetzt gibt es Genius Mixe. Du brauchst den iPod touch nur mit iTunes zu synchronisieren. Genius durchsucht dann automatisch deine Mediathek nach Songs, die gut zusammenpassen und erstellt bis zu zwölf Mixe.
Diese Mixe sind wie Radiosender, auf denen nur deine Musik läuft.
 
Genius Wiedergabelisten
Angenommen du hörst einen Song auf deinem iPod touch, der dir gut gefällt, und du möchtest weitere Titel hören, die dazu passen. Genius findet weitere Songs auf deinem iPod touch und erstellt eine Genius Wiedergabeliste für dich. Hör dir die Wiedergabeliste sofort an, speichere sie für später oder versuch's noch einmal und sieh, was dabei herauskommt. Verlass dich auf Genius, wenn du einen Mix willst, auf den du selbst nie gekommen wärst.
 
Shake to Shuffle
Die Dinge mal aufrütteln. Musikalisch natürlich. Wenn du das nächste Mal Musik hörst, aktiviere die Schüttelfunktion und wenn du den iPod touch dann kurz schüttelst, springt er nach dem Zufallsprinzip zu einem anderen Song aus deiner Sammlung.

iTunes
Pack Musik und Videos aus der iTunes Mediathek deines Computers auf den iPod touch. Oder kauf und lade neue Songs auf den iPod touch, wenn du über Wi-Fi auf iTunes zugreifst. Wenn du den iPod touch das nächste Mal mit dem Computer verbindest, werden alle Songs, die du auf dem iPod touch gekauft hast, auf den Mac oder PC übertragen.
 
Bluetooth
Schau mal, keine Kabel. Der iPod touch enthält die iPhone 3.1 Software, sodass du Bluetooth Stereokopfhörer anschließen kannst. Lass den iPod in deiner Tasche stecken oder auf dem Schreibtisch aufladen, während du weiter Musik hörst.
 
Filme und Fernsehsendungen
Ein Kinohit. Ein Video-Podcast. Deine Lieblingsserie. Jetzt laufen sie auch in einer U-Bahn oder einem Flugzeug in deiner Nähe.
 
Widescreen-Display
Du kannst Videos für viele Stunden überallhin mitnehmen und auf dem gestochen scharfen 3,5"" Widescreen-Farbdisplay ansehen. Kauf im iTunes Store und wähle unter tausenden vonFilmen, Fernsehsendungen und Video-Podcasts, die du auf den iPod touch laden kannst. Von Hollywood-Hits bis zu Indie-Streifen - es gibt etwas für jeden Geschmack. Mit wenigen Fingertipps kannst du Filme kaufen und laden. Du magst lieber Fernsehsendungen? Lade eine einzelne Folge oder die gesamte Staffel.
 
On-Screen Steuerung
Auch während du Video guckst, kannst du die Steuerung einblenden - ein Fingertipp auf das Display genügt. Du kannst die Wiedergabe starten oder unterbrechen, einzelne Kapitel anzeigen und die Lautstärke anpassen. Natürlich kannst du auch die Lautstärkeregler links am iPod touch verwenden. Du willst zwischen Widescreen und bildschirmfüllender Anzeige wechseln? Einfach aufs Display doppeltippen.
 
iTunes
Du brauchst Unterhaltung für deinen nächsten Flug oder die Autofahrt? Mit iTunes auf dem iPod touch und einer Wi-Fi-Verbindung kannst du auch unterwegsFilme und Fernsehsendungen kaufen. Du kannst Filme auch leihen, wenn du dir nicht sicher bist, ob du den Film behalten willst. Und natürlich kannst du Filme und Fernsehsendungen auf dem Mac oder PC kaufen und dann mit dem iPod touch synchronisieren.
 
App Store
Kaufe im App Store und entdecke über 65.000 Apps, mit denen du noch mehr auf dem iPod touch machen kannst. Stöbere in tausenden von Apps in verschiedenen Kategorien. Von Spielen über Lifestyle und Soziale Netzwerke bis zu Unterhaltung und mehr.
 
Apps durchstöbern
Du kannst auf verschiedene Arten im App Store shoppen. Tipp auf ""Neu"" und ""Topaktuell"", um eine Liste der aktuellen und angesagten Apps zu erhalten. Stöbere nach Kategorien. Schau dir die topaktuellen Apps an. Wenn du genau weißt, wonach du suchst, kannst du auch eine Schnellsuche durchführen.
 
Genius Empfehlungen für Apps
Es gibt tausende von Apps im App Store, und jeden Tag kommen mehr dazu. Mit dieser neuen Funktion des iPod touch findest du coole neue Apps noch einfacher. Genius für Apps. Funktioniert genau wie Genius für deine Musik. Tipp auf das Genius Symbol und du bekommst Empfehlungen für Apps anhand der Apps, die du und andere schon geladen haben.
 
Apps laden
Wenn du eine App findest, die dich interessiert, kannst du sie überall, wo eine Wi-Fi-Verbindung besteht, drahtlos kaufen, auf den iPod laden und dann sofort loslegen.
 
Updates für Apps
iPod touch sagt dir, wenn ein App Update verfügbar ist, damit du immer die neuesten Versionen deiner Lieblings-Apps hast.
 
iTunes
Entdecke und lade neue Musik, Filme, Fernsehsendungen, Podcasts und Hörbücher in iTunes auf dem iPod touch.
 
Einkaufen, immer und überall
Greif über die im iPod touch integrierte Wi-Fi-Funktion auf den iTunes Store zu. Durchsuche Millionen von iTunes Plus Songs in brillanter Audioqualitätund tausende von Filmen, Fernsehsendungen, Hörbüchern und kostenlosen Podcasts und Vorlesungen von iTunes U. Stöbere nach Neuerscheinungen, Top-Titeln und Genres. Oder finde mit der Schnellsuche genau das, wonach du suchst. Hör in einen Song oder sieh dir eine Videovorschau an. Wenn du dann etwas kaufen möchtest, brauchst du nur darauf zu tippen. Nicht sicher, ob es sich lohnt, den Film zu kaufen? Dann leih ihn einfach. Alles was du auf dem iPod touch kaufst, hat denselben Preis wie im iTunes Store auf deinem Computer.
 
Synchronisieren mit iTunes
Sobald du den iPod touch mit dem Computer verbindest, werden die Songs, Filme, Fernsehsendungen, Hörbücher und Podcasts, die du unterwegs geladen hast, mit deiner iTunes Mediathek auf deinem Mac oder PC synchronisiert. Wenn du etwas nur teilweise auf den iPod touch geladen hast, beendet der Computer den Download automatisch für dich.
 
Sprachsteuerung
Mit der Sprachsteuerung beim neuen 32 GB und 64 GB iPod touch kannst du deine Musik mit Sprachbefehlen steuern. Und der iPod hört aufs Wort. Auf ""Spiel"", ""Shuffle"" oder ""Wie heißt das Lied?"".
Sagen und abspielen.
Die Sprachsteuerung kennt die Musik auf deinem iPod touch. Wenn du etwas Bestimmtes hören willst, sag es einfach. Zum Beispiel ""Spiel Bob Dylan"" und der iPod touch hört aufs Wort. Frag ihn, welcher Song grad läuft, und der iPod touch sagt es dir. Sag ihm, dass er dein Lieblingsalbum, deinen Lieblingssänger oder deine Lieblingswiedergabeliste spielen soll. Verwende einfache Befehle wie ""shuffle"", ""nächster Song"" und ""anhalten"". Du kannst dem iPod touch sogar sagen, dass er mehr Songs wie den, der gerade läuft, abspielen soll.
 
Sprich ins Mikro
Der neue 32 GB und 64 GB iPod touch wird mit den Apple Earphones mit Fernbedienung und Mikro geliefert. So kannst du die Sprachsteuerung auch dann nutzen, wenn der iPod touch in der Tasche steckt. Zum Aktivieren der Sprachsteuerung über die Kopfhörer hältst du einfach die Mitteltaste der Fernbedienung gedrückt.
Die Sprachsteuerung unterstützt die folgenden Sprachen:
Chinesisch (China), Chinesisch (Kantonesisch), Chinesisch (Taiwan), Deutsch, Englisch (Großbritannien), Englisch (USA), Finnisch, Französisch (Frankreich), Französisch (Kanada), Italienisch, Japanisch, Koreanisch, Niederländisch, Norwegisch, Polnisch, Portugiesisch (Brasilien), Portugiesisch (Portugal), Russisch, Schwedisch, Spanisch (Mexiko), Spanisch (Spanien)
 
Fotos
Der iPod touch hat für bis zu 90.000 deiner Lieblingsfotos Platz. Durch Streichen kannst du sie durchschauen und all die Erinnerst-du-dich-noch-Momente mit anderen teilen.
 
Fotos sichern
Wenn dir tolle Bilder gemailt werden, kannst du sie einfach im Fotoarchiv auf dem iPod touch sichern und dann wie jedes andere Foto nutzen. Du kannst sie zum Beispiel als Hintergrundbilder verwenden, im Internet teilen oder weitergeben.
 
Fotos teilen
Du hast tausende Fotos immer zur Hand. Blätter durch Streichen auf dem Display durch Miniaturen. Mit einem Fingertipp siehst du Fotos bildschirmfüllend. Spiel Diashows mit Musik und Übergängen ab. Maile Fotos an Freunde oder teile sie in einer MobileMe Galerie.
 
Fotos synchronisieren
Fotos aus iPhoto auf einem Mac oder Adobe Photoshop Elements und Adobe Photoshop Album auf einem PC werden via iTunes mit dem iPod touch synchronisiert. Einfach nur die Fotos und Alben aussuchen, die mit dem iPod touch synchronisiert werden sollen. Dann kannst du sie überall ansehen und mit anderen teilen.

Homescreen
Angenommen du möchtest ""Karten"" als erste App in der zweiten Zeile haben. Oder Mail unten im Dock. Mit den anpassbaren Homescreens kannst du den iPod touch zu deinem iPod touch machen.
 
Individuelles Anpassen
Ordne die Symbole auf deinem Homescreen an wie du willst - direkt auf dem iPod touch oder auf deinem Computer in iTunes 9. Bewege eine App eine Zeile nach oben, zwei Apps nach rechts oder auf einen anderen Homescreen. Du kannst bis zu 11 Homescreens erstellen und hast so schnellen Zugriff auf Spiele und Apps, die du aus dem App Store lädst, und auf deine Safari Weblinks.
 
Hometaste
Was auch immer du gerade mit deinem iPod touch machst – die Hometaste bringt dich immer zurück zum ersten Homescreen. Wenn du auf die Hometaste drückst, kannst du von jedem Homescreen wieder zurück zum ersten springen.
 
Apps und Weblinks hinzufügen
Für jede App, die du aus dem App Store lädst, erscheint ein neues Symbol auf dem Homescreen. Von häufig besuchten Websites kannst du praktische Weblinks erstellen. Sie erscheinen auf dem Homescreen und du kannst per Fingertipp darauf zugreifen.
 
Spotlight Suche
Du suchst was? Von einem Ort aus kannst du die gesamten Inhalte des iPod touch durchsuchen. Streich auf dem ersten Homescreen einfach nach rechts, um Spotlight zu öffnen. Sobald du anfängst zu tippen, durchsucht Spotlight deine gesamten Songs, Videos, Kontakte, Mails, Kalender, Notizen und sogar deine Hörbücher und Podcasts.
 
Safari
Safari, der fortschrittlichste Webbrowser auf einem Mobilgerät, ist auch auf dem iPod touch integriert. Damit erlebst du das Internet in deiner Hand genauso wie auf dem Computer zuhause. Alles was du brauchst ist eine Wi-Fi-Verbindung.
 
Überall ins Internet
Der iPod touch ist der einzige iPod mit integriertem drahtlosen Internetzugriff. Bei bestehender Wi-Fi-Verbindung kannst du im Internet surfen und Nachrichten lesen, Sportergebnisse sehen, Rechnungen bezahlen und online einkaufen. Und beim 32 GB oder 64 GB iPod touch wirst du sehen, dass Webseiten jetzt noch schneller als vorher geladen werden.
 
Im Web stöbern
Der iPod touch synchronisiert deine Lesezeichen vom PC oder Mac, sodass du ruckzuck auf deine Lieblingsseiten zugreifen kannst. Außerdem ist die Google- und Yahoo!-Suche schon integriert, sodass du im Web schnell findest, was du suchst.
 
Weblinks
Wenn du eine Website öfter besuchst - etwa die einer Zeitung, eines Blogs oder eine Sport-Website - kannst du einfach ein Symbol, einen sogenannten Weblink, auf dem Homescreen erstellen. Wenn du mit Safari Weblinks erstellst, sind deine Lieblingsseiten nur einen Fingertipp entfernt.
 
Zoom
Wenn du eine Website öfter besuchst, brauchst du nur mit dem Finger auf das Multi-Touch-Display zu tippen oder die Anzeige aufzuziehen. Websites lassen sich im Hoch- oder Querformat anzeigen. Einfach den iPod touch um 90 Grad drehen, und schon wird auch die Darstellung der Webseite gedreht.
 
Mail
Mails auf dem iPod touch funktionieren genau wie auf deinem Computer und sehen auch genau so aus. Und sie funktionieren mit deinen vorhandenen Accounts.
 
Nachrichten und Anhänge ansehen
Der iPod touch unterstützt Rich-HTML-E-Mail, sodass Bilder und Fotos zusammen mit dem Text einer E-Mail angezeigt werden. Anhänge siehst du in ihrem Originalformat und nicht als abgespeckte Version. Du kannst in mehr als einem Dutzend standardmäßigen Datei- und Bildformaten drehen, zoomen und schwenken, darunter PDF, Microsoft Word, Excel, PowerPoint und iWork.
 
Zugriff auf alle Accounts
Mails von gängigen Anbietern wie MobileMe, Google Mail, Microsoft Exchange, Yahoo! und den meisten standardmäßigen IMAP- und POP-Systemen kannst du mit dem iPod touch ganz einfach abrufen.
 
Schnellere Eingabe
Der iPod touch erkennt E-Mail-Adressen in verschiedenen Programmen. Wenn du auf einer Webseite oder in einer Karte eine E-Mail-Adresse siehst, reicht ein Fingertipp auf dem iPod touch, um eine neue Mail zu öffnen, in der die Adresse bereits eingetragen ist.
 
Intelligente Eingabe
Die innovative iPod touch Tastatur mit integriertem Wörterbuch* schlägt während der Eingabe Wörter vor. So kannst du ganz schnell und einfach Mails schreiben. Dreh den iPod touch einfach. Dann wird die Tastatur vom Hochformat ins Querformat gedreht und du hast größere Tasten und mehr Platz zum Tippen.
 
Postfach durchsuchen
Du musst das Postfach jetzt nicht mehr Mail für Mail durchsuchen. Durch schnelles Abwärtsstreichen wird jetzt ein Suchfeld geöffnet, mit dem du deine Mails nach Absender, Empfänger, Betreff oder Titelzeilen durchsuchen kannst.
 
Karten
Finde deinen Weg und die nächste Pizzeria. Mit Karten und einer Wi-Fi-Verbindung kannst du Wegbeschreibungen abrufen, Firmen finden und Verkehrsinformationen prüfen.
 
Finde dich selbst
Der iPod touch zeigt dir mithilfe von bekannten Wi-Fi-Hot-Spots, wo du bist. Mit der Stichwortsuche kannst du auch interessante Orte finden. Wenn du z. B. ""Kaffee"" eingibst, werden dir alle Cafés in der Nähe angezeigt.
 
Wo geht's lang?
Gib einfach eine Adresse ein, um Wegbeschreibungen abzurufen - von jedem Ort aus. Wähle das Transportmittel wie Auto, öffentliches Verkehrsmittel oder zu Fuß. Die Route lässt sich dann Schritt für Schritt anzeigen. Du kannst dem markierten Weg auf der Karte folgen und selbst die Fahrtdauer wird angezeigt. Oder markiere zwei Orte und lass dir die beste Route zwischen diesen anzeigen.
 
Verschiedene Kartendarstellungen
Wie bei Google Karten auf deinem Computer kannst du mit dem Programm ""Karten"" auf dem iPod touch zwischen unterschiedlichen Darstellungen von Google-Karten, Satellitenbildern und einer Hybriddarstellung wechseln. Und mit Multi-Touch kannst du unterwegs zoomen, den Ausschnitt bewegen und die Darstellung ändern.
 
Verkehrsinformationen
Die Verkehrsinformationen geben dir anhand der grünen, roten und gelben Markierungen einen Überblick über die Verkehrssituation auf deiner Route.
 
YouTube
Skateboard Moves, die so nicht geplant waren. Witzige Werbespots aus anderen Ländern. Was auch immer du gern auf YouTube ansiehst - der iPod touch ist für dich da.
 
Videogrüße von unterwegs.
Maile Links deiner Lieblingsvideos an Freunde. Tippe auf der Detailseite des YouTube Videos auf ""Senden"", und schon erstellt der iPod touch eine Mail mit dem zugehörigen Videolink.
 
Auf YouTube suchen.
Stöber in Videokategorien wie ""Highlights"", ""Topvideos"", ""Neue Videos"" oder ""Bestwertung"". Du kannst auch per Schlagwort nach einem Video suchen. Etwas Passendes gefunden? Mit einem Lesezeichen kannst du das Video auch vormerken und später ansehen.
 
Nike + iPod Kompatibilität
Rock dein Training. Der iPod touch hat eine integrierte Unterstützung für Nike + iPod. Das ist Musik und Motivation in einem.
Finetuning für dein Lauftraining.
 
Nike + iPod Sensor
Der iPod touch hat eine integrierte Unterstützung für Nike + iPod. Einfach den Nike + iPod Sensor (separat erhältlich) in die Nike+ Schuhe stecken und los geht's. Der Sensor überträgt deine Laufdaten drahtlos an den iPod touch und zeichnet Laufzeit, Laufstrecke und Kalorienverbrauch auf. Du erhältst sogar Feedback zum Trainingsfortschritt.
 
Finetuning für dein Cardio Workout
Diese Funktion kann auch zusammen mit neuen, in vielen Fitnessstudios vorhandenen Geräten für das Ausdauertraining gekoppelt werden. Such dir einfach ein mit Nike + iPod kompatibles Fitnessgerät wie beispielsweise Laufbänder, Ellipsentrainer, Stepper und Hometrainer.
 
Synchronisieren mit nikeplus.com
Später kannst du am Computer den iPod touch via iTunes synchronisieren und deine Trainingsdaten an nikeplus.com übertragen. Auf dieser Website kannst du dein Training verfolgen, dir Ziele setzen und deine Freunde herausfordern.
 
Sprachmemos
Du hast vielleicht ein ganz gutes Gedächtnis, aber manchmal ist es besser, kleine (und große) Infos einfach irgendwo festzuhalten. Mit ""Sprachmemos"" kein Problem.

Memos (oder alles andere)aufnehmen
Nimm eine Aufgabenliste, geniale Ideen oder eine Wette zwischen dir und deinem Freund auf. Mit dem Programm ""Sprachmemos"" kannst du über die Apple Earphones mit Fernbedienung und Mikro oder ein externes Mikrofon aufnehmen, was immer du willst. Sprachmemos kannst du selbst dann aufnehmen, wenn du den iPod touch gerade verwendest, um Mails zu checken oder im Web zu surfen.
Memos bearbeiten
Aufgenommene Memos kannst du direkt auf dem iPod touch trimmen. So behältst du nur das, was du wirklich brauchst.
Memos sortieren
Ordne deine Memos mithilfe von Etiketten aus einer vordefinierten Liste oder erstelle eigene Etiketten.
Memos teilen
Maile Memos an Freunde und Kollegen. Mit dem iPod touch aufgenommene Memos werden via iTunes mit deinem Mac oder PC synchronisiert, damit du sie später mit anderen teilen kannst.
Weitere Funktionen
Auf dem iPod touch ist die neueste Software schon installiert. Und außerdem gibt's praktische Apps wie Kontakte, Kalender, Notizen, Aktien und Wetter.
 
iPod touch 3.1 Softwarefunktionen.
 
Genius Mixe
Diese neue Funktion ist wie ein privater DJ, der deine iTunes Mediathek durchsucht, um Songs zu finden, die gut zusammenpassen und aus diesen dann tolle Mixe erstellt. Alles ganz automatisch.
Genius Empfehlungen für Apps
Im App Store gibt's zehntausende Apps. Wie soll man da die richtig collen neuen finden? Mit Genius. Denn Genius sieht sich die Apps an, die du schon hast, und empfiehlt dir weitere.
 
Peer-to-Peer-Spiele
Die neusten Spiele kannst du ganz leicht mit Freunden spielen - egal, ob sie neben dir oder in einer anderen Ecke des Landes sitzen.
 
Kauf Filme, Fernsehsendungen und Hörbücher via Wi-Fi
Lade via Wi-Fi Filme, Fernsehsendungen, Musikvideos und Hörbücher aus dem iTunes Store auf deinen iPod touch.
 
Tastatur im Querformat
Du brauchst mehr Platz zum Tippen? Dreh den iPod touch ins Querformat, um in Mail, Notizen und Safari mit einer größeren Tastatur zu arbeiten.
 
Cut, Copy & Paste
Einfach Text und Fotos ausschneiden, kopieren und wieder einsetzen - selbst zwischen Programmen. Du kannst auch Inhalte aus dem Web kopieren.
 
Spotlight Suche
Gesucht, gefunden - von einem Ort aus. Spotlight durchsucht alle deine Kontakte, E-Mails, Kalender und Notizen und auch alle Songs und Videos.
 
Stereo Bluetooth
Hör Musik und andere Audioinhalte drahtlos. Verbinde den iPod touch mit kompatiblen Bluetooth Stereokopfhörern.

Automatischer Wi-Fi-Login
Wenn du dich einmal bei einem Wi-Fi-Hotspot anmeldest, loggt der iPod touch sich beim nächsten Mal automatisch ein.
 
Shake to Shuffle
Schüttel den iPod kurz, und schon springt er nach dem Zufallsprinzip zu einem anderen Song in deiner Sammlung. Lass dich einfach überraschen.
 
Bedienungshilfen
Der neue iPod touch hat standardmäßig Bedienungshilfen integriert, mit denen auch Menschen mit Beeinträchtigungen alles, was der iPod touch zu bieten hat, erleben können. Alle Bedienungshilfen des iPod touch ansehen
 
Kindersicherung
Du entscheidest, welche Musik, Videos und Apps auf dem iPod touch für deine Kinder geeignet sind.
Der iPod touch hat auch die folgenden praktischen Apps:
 
Kalender
Das Programm ""Kalender"" funktioniert mit Yahoo!, Google, Microsoft Outlook, iCal, MobileMe und Microsoft Exchange ActiveSync für Unternehmen. Füge Termine hinzu, lass dich an Termine erinnern, und abonniere Kalender, damit du über Feiertage und Sportveranstaltungen auf dem Laufenden bleibst.
 
Kontakte
Namen, E-Mail-Adressen, Telefonnummern und mehr - immer zur Hand. Synchronisier Kontakte in iTunes auf dem Mac oder PC mit dem iPod touch. Neue Kontakte kannst du auch unterwegs mit einem einfachen Fingertipp hinzufügen.
 
Notizen
Schluss mit Papier und Bleistift. Mach dir mit ""Notizen"" auf dem iPod schnell eine Notiz, damit du wichtige Infos immer parat hast. Maile deine Gedanken mit der integrierten Mail-Funktion an dich oder andere.
 
Aktien
Die Aktien App auf dem iPod touch zeigt dir Börseninformationen für die Aktien, die dich interessieren. Wenn du nähere Details über eine Aktie brauchst, tipp auf ""Y!"", um im Handumdrehen Yahoo! Finance zu öffnen.
 
Wetter
Informier dich über das Wetter in der ganzen Welt oder zuhause. Füge die gewünschten Städte hinzu und zeige eine sechstägige Vorhersage für alle an. Tipp auf ""Y!"", um den Yahoo! Stadtführer zu öffnen, der dir zeigt, wo was los ist.
 
Rechner
Im Programm ""Rechner"" des iPod touch stecken gleich zwei Rechner. Im Hochformat kannst du ihn als einfachen Taschenrechner verwenden. Dreh den iPod touch ins Querformat, um aus ihm einen wissenschaftlichen Rechner zu machen.
 
iPod touch Technologie
Dank der revolutionären Hardwaretechnologie im iPod touch kannst du alle Funktionen mit Streichen, Tippen und Auf- oder Zuziehen steuern. Deswegen wirkt das Autorennen so echt. Deswegen kannst du das, was du eben im Café mitbekommen hast, sofort twittern. Und genau deswegen ist der iPod touch der beste iPod aller Zeiten.
 
Multi-Touch
Das Multi-Touch-Display besitzt einen Schutzfilm über der kapazitiven Sensorik, die Berührungen anhand elektrischer Felder erkennt. Diese Informationen werden an das darunterliegende LCD-Display übertragen. Dank der Software des iPod touch kannst du mit Cover Flow durch Alben stöbern, durch deine Fotos blättern, mit Auf- und Zuziehen Bildausschnitte von Websites zoomen und Spiele superpräzise steuern.

Beschleunigungssensor
Der iPod touch reagiert über einen integrierten Beschleunigungssensor auf Bewegungen. Dieser Sensor erkennt, wenn du deinen iPod touch ins Querformat drehst und verändert automatisch den Inhalt des Displays. Die Technologie des Beschleunigungssensors kommt besonders bei Spielen gut, denn damit bist du mitten im Spielgeschehen. Das ist perfekt für Autorennen, bei denen der ganze iPod zum Lenkrad wird, und Geschicklichkeitsspiele wie Rolando, bei denen du das Spiel mit deinen Bewegungen steuerst
 
Drahtlos
Der iPod touch hat eine integrierte Unterstützung für drahtlosen 802.11b/g Internetzugriff. Überall, wo es ein Wi-Fi-Netzwerk gibt, kommst du mit deinem iPod touch ins Internet. Im Café mailen. Am Flughafen im Web surfen. Spiele vom Sofa aus kaufen. Im iTunes Store stöbern und Musik kaufen und laden. Der iPod touch findet nahegelegene Wi-Fi-Hot-Spots, auch geschützte Netzwerke. Wenn du ein bestimmtes Netzwerk bisher noch nicht verwendet hast, Drahtlos Symbol musst du beim ersten Mal ein Kennwort eingeben, das sich der iPod touch dann merkt. Wenn du dann das nächste Mal in Reichweite dieses Netzwerks bist, loggt er sich automatisch ein.
 
Bluetooth
Bluetooth ist eine drahtlose Technologie, mit der du Geräte ohne lästige Kabel verwenden kannst. Was bedeutet das für den iPod touch? Du kannst jetzt mit dem iPod touch und Bluetooth Kopfhörern Musik hören, ganz egal, wo im Raum der iPod ist. Du kannst also auf dem Bett relaxen, während der iPod auf dem Schreibtisch aufgeladen wird. Bluetooth auf dem iPod touch eignet sich auch besonders für Peer-to-Peer-Spiele.
 
Design
Der iPod touch ist von außen genau so großartig wie von innen. Du brauchst nur einen in die Hand zu nehmen. Das Gehäuse des iPod touch ist gerade einmal 8,5 mm hoch. Das optische Glas auf der Vorderseite und die Rückseite aus poliertem Edelstahl geben ihm einen eleganten Touch und fühlen sich in der Hand einfach gut an. Schalte ihn ein und du wirst über das brillante 3,5"" Display einfach staunen. Der iPod touch ist die perfekte Kombination aus großartigem Design und revolutionärer Technologie - das perfekte Paket.
";2;False;0;;;Apple iPod Touch 64 GB schwarz mit integrierter WiFi Funktion;apple-ipod-touch-64-gb-schwarz;True;True;P-1280;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;349.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40186,8528819444;44;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000434-apple-ipod-touch-64-gb-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000435-apple-ipod-touch-64-gb-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000436-apple-ipod-touch-64-gb-schwarz.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Apple iPod shuffle 2 GB grün;Apple iPod shuffle 2 GB grün;"

Apple iPod shuffle 2GB grün
 

Wie seine größeren Geschwister besitzt auch der iPod shuffle kreisförmig angeordnete, ergonomische Bedienelemente.
Der Kopfhöreranschluss am iPod shuffle dient gleichzeitig als Dock-Anschluss. Drehen Sie den iPod shuffle auf die Seite und setzen Sie ihn in das mitgelieferte Dock ein.
Dank eines stabilen, integrierten Clips lässt sich der iPod shuffle fast überall befestigen. Klemmen Sie ihn am T-Shirt, am Hemdkragen oder am Trageriemen von Rucksack oder Handtasche fest.
Lassen Sie sich aufs Ungewisse ein: Verwenden Sie den Schalter für die Zufallswiedergabe, um den Inhalt Ihres iPod shuffle neu zu mischen.
verbesserte Kopfhörer und das neue iTunes 8.0
 
Einfach Musik anhaben mit dem Apple iPOD SHUFFLE 2GB.Tragen Sie bis zu 500 Songs am Ärmel. Oder am Gürtel. Oder am Sportoutfit. Das Erkennungszeichen für Musikfans - den Apple iPOD SHUFFLE. Füllen Sie Ihren Apple iPOD SHUFFLE silber 1GB spielend einfach. iTunes ist der Store für Unterhaltungsinhalte. Ihre super organisierte Musiksammlung und Jukebox. Und die Software, mit der Sie Ihren Apple iPOD SHUFFLE mit einem Mausklick füllen. Das farbige Gehäuse aus eloxiertem Aluminium in silber passt zum genial einfachen Design des Apple iPOD SHUFFLE.
 
Leistungseigenschaften
 
2 GB Flash-Memory Speicher
min. Audio-Datenrate: 8 KBit/s
max. Audio-Datenrate: 320 KBit/s
Frequenzgang-Untergrenze: 20 Hz
Frequenzgang-Obergrenze: 20000 Hz
 
Formate/Standards
 
MP3-Standard
AAC + MP3 Standard
WAV-Dateiformat kompatibel
Audible-Format kompatibel
AIFF-Format kompatibel
 
Bedienung
 
Musiktitel-Verwaltung
 
Leistungsaufnahme/Spannungsversorgung

Li-Polymer Akku
12 Std. Spieldauer mit Akku
Ladezeit für Akku: 4 Std.
 
Anschlüsse
 
Kopfhörer-Anschluß
USB-Schnittstelle
Anschluß für Docking-Station
 
Gehäuse-Eigenschaften
 
Breite: 4.12 cm
Höhe: 2.73 cm
Tiefe: 1.05 cm
Gewicht: 15.5 g

";2;False;0;;;Apple iPod shuffle 2 GB grün;apple-ipod-shuffle-2-gb-gruen;True;True;P-1140;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;64.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40186,8481481482;37;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000429-apple-ipod-shuffle-2-gb-grun.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000430-apple-ipod-shuffle-2-gb-grun.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000431-apple-ipod-shuffle-2-gb-grun.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Apple iPod shuffle 2 GB schwarz;Apple iPod shuffle 2 GB schwarz;"
Apple iPod shuffle 2GB schwarz
 
 
Der kleinste iPod der Welt
 
 
Um den kleinsten iPod der Welt zu bauen, haben wir die Steuerung vom iPod shuffle in das Ohrhörerkabel integriert.
So wird der iPod shuffle noch kleiner und die Steuerung ist genau da, wo du sie einfach erreichst.
Wenn du einen Song abspielen, anhalten oder überspringen möchtest,
musst du nicht lange nach dem iPod shuffle suchen - greif einfach zum Kabel und drücke auf eine der Tasten.
Dieser Entertainment-Winzling sagt Ihnen auf Knopfdruck, welchen Titel er gerade abspielt
Organisieren Sie Ihre Musik in verschiedenen Wiedergabeslisten
Dank eines stabilen, integrierten Clips lässt sich der iPod shuffle fast überall befestigen.
Lassen Sie sich aufs Ungewisse ein: Verwenden Sie den Schalter für die Zufallswiedergabe,
um den Inhalt Ihres iPod shuffle neu zu mischen.
Lieferumfang: Apple Earphones mit Remote Fernbedienung
 
iPod shuffle - In leuchtenden neuen Farben spricht Musik dich richtig an
 
Der kleinste iPod der Welt
Um den kleinsten iPod der Welt zu bauen, haben wir die Steuerung vom iPod shuffle in das Ohrhörerkabel integriert. So wird der iPod shuffle noch kleiner und die Steuerung ist genau da, wo du sie einfach erreichst. Wenn du einen Song abspielen, anhalten oder überspringen möchtest, musst du nicht lange nach dem iPod shuffle suchen - greif einfach zum Kabel und drücke auf eine der Tasten.
 
Der erste iPod, der mit dir spricht
Die VoiceOver Funktion ist mit Sicherheit der nächste Hit auf dem iPod shuffle.1 Angenommen du hörst einen Song und willst wissen, wie er heißt oder von wem er ist: Einfach Knopf drücken und VoiceOver sagt es dir. Sogar die Namen deiner Wiedergabelisten verrät es dir. Und wenn die Batterie aufgeladen werden muss, sagt VoiceOver dir das auch.
 
Leichtbedienung
Die Steuerung befindet sich am Kabel des rechten Ohrstöpsels. Dadurch, dass die Steuerung jetzt hier angebracht ist, kannst du deine Musiktitel durchsuchen - und die VoiceOver Funktion aktivieren - ohne vom Joggen, Rad fahren oder anderen Aktivitäten abgelenkt zu werden. Der iPod shuffle wird mit dieser einfachen Steuerung geliefert. Du kannst aber auch Kopfhörer mit ähnlichen Bedienelementen von Herstellern wie Scosche, Klipsch, V-MODA und Belkin verwenden.
 

Dein Musikarchiv. Für unterwegs
Der iPod shuffle kommt jetzt mit 2 GB oder 4 GB. Mit dem 4 GB Modell hast du jede Menge Platz, um Musik für viele Stunden - bis zu 1.000 Songs - zu speichern.2 Damit bist du im Fitnessstudio oder auf dem Weg zur Arbeit bestens gerüstet. Außerdem kannst du jetzt mehrere Wiedergabelisten und auch Hörbücher verwenden.
 
Mehrere Wiedergabelisten
Wahrscheinlich hast du dir in iTunes schon einige Wiedergabelisten zusammengestellt. Eine für unterwegs. Eine fürs Fitnessstudio. Eine zum Chillen. Jetzt kannst du deine Wiedergabelisten auf dem Computer mit dem iPod shuffle synchronisieren und hast immer genau den richtigen Mix - egal, was du gerade machst oder in welcher Stimmung du bist. VoiceOver nennt dir den Namen jeder Wiedergabeliste. So kannst du ganz leicht zwischen ihnen wechseln und genau die auswählen, nach der dir gerade ist.
 
Farbe bekennen
Mit dem flachen, robusten Gehäuse aus eloxiertem Aluminium ist der iPod shuffle immer das passende Accessoire. In leuchtendem Pink, Blau, Grün, Schwarz oder Silber ist er ein echtes Fashion Statement. Ganz neu dabei: der iPod shuffle Special Edition in poliertem Edelstahl (So werden Rockstars nun mal behandelt). Sogar der iPod shuffle Clip sieht stylish aus. Er klemmt sicher an Hemd, Jacke, Sportzeug oder am Rucksack. So wird der iPod shuffle zum perfekten Fashtech-Accessoire. Und klar, natürlich ist noch Platz für eine persönliche Gravur.

Mehrsprachig
Ein französisches Chanson. Ein spanischer Bolero. Eine italienische Arie. Dein Musikarchiv enthält Musik aus allen Ländern der Welt. Deshalb spricht VoiceOver 20 Sprachen und kann die Namen von Songs und Interpreten mit der richtigen Aussprache sprechen.
 
Zufall oder kein Zufall?
Der Schalter am iPod shuffle hat drei Einstellungen. Links wird deine Musik zufällig durcheinander gewürfelt. In der Mitte werden deine Songs in der normalen Reihenfolge gespielt. Rechts wird der iPod shuffle ausgeschaltet.
";2;False;0;;;Apple iPod shuffle Tragbarer MP3-Player 4 GB 3. Generation;apple-ipod-shuffle-2-gb-schwarz;True;True;P-1200;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;61.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40186,8421875;39;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000585-apple-ipod-shuffle-4-gb-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000586-apple-ipod-shuffle-4-gb-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000587-apple-ipod-shuffle-4-gb-schwarz.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Apple iPod shuffle 2 GB pink;Apple iPod shuffle 2 GB pink;"

Apple iPod shuffle 2 GB pink 

Der kleinste iPod der Welt
 
 
Um den kleinsten iPod der Welt zu bauen, haben wir die Steuerung vom iPod shuffle in das Ohrhörerkabel integriert.
So wird der iPod shuffle noch kleiner und die Steuerung ist genau da, wo du sie einfach erreichst.
Wenn du einen Song abspielen, anhalten oder überspringen möchtest,
musst du nicht lange nach dem iPod shuffle suchen - greif einfach zum Kabel und drücke auf eine der Tasten.
Dieser Entertainment-Winzling sagt Ihnen auf Knopfdruck, welchen Titel er gerade abspielt
Organisieren Sie Ihre Musik in verschiedenen Wiedergabeslisten
Dank eines stabilen, integrierten Clips lässt sich der iPod shuffle fast überall befestigen.
Lassen Sie sich aufs Ungewisse ein: Verwenden Sie den Schalter für die Zufallswiedergabe,
um den Inhalt Ihres iPod shuffle neu zu mischen.
Lieferumfang: Apple Earphones mit Remote Fernbedienung
 
iPod shuffle - In leuchtenden neuen Farben spricht Musik dich richtig an
 
Der kleinste iPod der Welt
Um den kleinsten iPod der Welt zu bauen, haben wir die Steuerung vom iPod shuffle in das Ohrhörerkabel integriert. So wird der iPod shuffle noch kleiner und die Steuerung ist genau da, wo du sie einfach erreichst. Wenn du einen Song abspielen, anhalten oder überspringen möchtest, musst du nicht lange nach dem iPod shuffle suchen - greif einfach zum Kabel und drücke auf eine der Tasten.
 
Der erste iPod, der mit dir spricht
Die VoiceOver Funktion ist mit Sicherheit der nächste Hit auf dem iPod shuffle.1 Angenommen du hörst einen Song und willst wissen, wie er heißt oder von wem er ist: Einfach Knopf drücken und VoiceOver sagt es dir. Sogar die Namen deiner Wiedergabelisten verrät es dir. Und wenn die Batterie aufgeladen werden muss, sagt VoiceOver dir das auch.
 
Leichtbedienung
Die Steuerung befindet sich am Kabel des rechten Ohrstöpsels. Dadurch, dass die Steuerung jetzt hier angebracht ist, kannst du deine Musiktitel durchsuchen - und die VoiceOver Funktion aktivieren - ohne vom Joggen, Rad fahren oder anderen Aktivitäten abgelenkt zu werden. Der iPod shuffle wird mit dieser einfachen Steuerung geliefert. Du kannst aber auch Kopfhörer mit ähnlichen Bedienelementen von Herstellern wie Scosche, Klipsch, V-MODA und Belkin verwenden.
 

Dein Musikarchiv. Für unterwegs
Der iPod shuffle kommt jetzt mit 2 GB oder 4 GB. Mit dem 4 GB Modell hast du jede Menge Platz, um Musik für viele Stunden - bis zu 1.000 Songs - zu speichern.2 Damit bist du im Fitnessstudio oder auf dem Weg zur Arbeit bestens gerüstet. Außerdem kannst du jetzt mehrere Wiedergabelisten und auch Hörbücher verwenden.
 
Mehrere Wiedergabelisten
Wahrscheinlich hast du dir in iTunes schon einige Wiedergabelisten zusammengestellt. Eine für unterwegs. Eine fürs Fitnessstudio. Eine zum Chillen. Jetzt kannst du deine Wiedergabelisten auf dem Computer mit dem iPod shuffle synchronisieren und hast immer genau den richtigen Mix - egal, was du gerade machst oder in welcher Stimmung du bist. VoiceOver nennt dir den Namen jeder Wiedergabeliste. So kannst du ganz leicht zwischen ihnen wechseln und genau die auswählen, nach der dir gerade ist.
 
Farbe bekennen
Mit dem flachen, robusten Gehäuse aus eloxiertem Aluminium ist der iPod shuffle immer das passende Accessoire. In leuchtendem Pink, Blau, Grün, Schwarz oder Silber ist er ein echtes Fashion Statement. Ganz neu dabei: der iPod shuffle Special Edition in poliertem Edelstahl (So werden Rockstars nun mal behandelt). Sogar der iPod shuffle Clip sieht stylish aus. Er klemmt sicher an Hemd, Jacke, Sportzeug oder am Rucksack. So wird der iPod shuffle zum perfekten Fashtech-Accessoire. Und klar, natürlich ist noch Platz für eine persönliche Gravur.

Mehrsprachig
Ein französisches Chanson. Ein spanischer Bolero. Eine italienische Arie. Dein Musikarchiv enthält Musik aus allen Ländern der Welt. Deshalb spricht VoiceOver 20 Sprachen und kann die Namen von Songs und Interpreten mit der richtigen Aussprache sprechen.
 
Zufall oder kein Zufall?
Der Schalter am iPod shuffle hat drei Einstellungen. Links wird deine Musik zufällig durcheinander gewürfelt. In der Mitte werden deine Songs in der normalen Reihenfolge gespielt. Rechts wird der iPod shuffle ausgeschaltet.
";2;False;0;;;Apple iPod shuffle 1GB;apple-ipod-shuffle-2-gb-pink-2;True;True;P-1190;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;59.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40186,8385648148;39;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000588-apple-ipod-shuffle-2-gb-pink.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000579-apple-ipod-shuffle-4-gb-blau.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000580-apple-ipod-shuffle-4-gb-blau.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Apple iPod shuffle 2 GB blau;Apple iPod shuffle 2 GB blau;"
Apple iPod shuffle 2GB blau
 
 
Der kleinste iPod der Welt
 
 
Um den kleinsten iPod der Welt zu bauen, haben wir die Steuerung vom iPod shuffle in das Ohrhörerkabel integriert.
So wird der iPod shuffle noch kleiner und die Steuerung ist genau da, wo du sie einfach erreichst.
Wenn du einen Song abspielen, anhalten oder überspringen möchtest,
musst du nicht lange nach dem iPod shuffle suchen - greif einfach zum Kabel und drücke auf eine der Tasten.
Dieser Entertainment-Winzling sagt Ihnen auf Knopfdruck, welchen Titel er gerade abspielt
Organisieren Sie Ihre Musik in verschiedenen Wiedergabeslisten
Dank eines stabilen, integrierten Clips lässt sich der iPod shuffle fast überall befestigen.
Lassen Sie sich aufs Ungewisse ein: Verwenden Sie den Schalter für die Zufallswiedergabe,
um den Inhalt Ihres iPod shuffle neu zu mischen.
Lieferumfang: Apple Earphones mit Remote Fernbedienung
 
iPod shuffle - In leuchtenden neuen Farben spricht Musik dich richtig an
 
Der kleinste iPod der Welt
Um den kleinsten iPod der Welt zu bauen, haben wir die Steuerung vom iPod shuffle in das Ohrhörerkabel integriert. So wird der iPod shuffle noch kleiner und die Steuerung ist genau da, wo du sie einfach erreichst. Wenn du einen Song abspielen, anhalten oder überspringen möchtest, musst du nicht lange nach dem iPod shuffle suchen - greif einfach zum Kabel und drücke auf eine der Tasten.
 
Der erste iPod, der mit dir spricht
Die VoiceOver Funktion ist mit Sicherheit der nächste Hit auf dem iPod shuffle.1 Angenommen du hörst einen Song und willst wissen, wie er heißt oder von wem er ist: Einfach Knopf drücken und VoiceOver sagt es dir. Sogar die Namen deiner Wiedergabelisten verrät es dir. Und wenn die Batterie aufgeladen werden muss, sagt VoiceOver dir das auch.
 
Leichtbedienung
Die Steuerung befindet sich am Kabel des rechten Ohrstöpsels. Dadurch, dass die Steuerung jetzt hier angebracht ist, kannst du deine Musiktitel durchsuchen - und die VoiceOver Funktion aktivieren - ohne vom Joggen, Rad fahren oder anderen Aktivitäten abgelenkt zu werden. Der iPod shuffle wird mit dieser einfachen Steuerung geliefert. Du kannst aber auch Kopfhörer mit ähnlichen Bedienelementen von Herstellern wie Scosche, Klipsch, V-MODA und Belkin verwenden.
 

Dein Musikarchiv. Für unterwegs
Der iPod shuffle kommt jetzt mit 2 GB oder 4 GB. Mit dem 4 GB Modell hast du jede Menge Platz, um Musik für viele Stunden - bis zu 1.000 Songs - zu speichern.2 Damit bist du im Fitnessstudio oder auf dem Weg zur Arbeit bestens gerüstet. Außerdem kannst du jetzt mehrere Wiedergabelisten und auch Hörbücher verwenden.
 
Mehrere Wiedergabelisten
Wahrscheinlich hast du dir in iTunes schon einige Wiedergabelisten zusammengestellt. Eine für unterwegs. Eine fürs Fitnessstudio. Eine zum Chillen. Jetzt kannst du deine Wiedergabelisten auf dem Computer mit dem iPod shuffle synchronisieren und hast immer genau den richtigen Mix - egal, was du gerade machst oder in welcher Stimmung du bist. VoiceOver nennt dir den Namen jeder Wiedergabeliste. So kannst du ganz leicht zwischen ihnen wechseln und genau die auswählen, nach der dir gerade ist.
 
Farbe bekennen
Mit dem flachen, robusten Gehäuse aus eloxiertem Aluminium ist der iPod shuffle immer das passende Accessoire. In leuchtendem Pink, Blau, Grün, Schwarz oder Silber ist er ein echtes Fashion Statement. Ganz neu dabei: der iPod shuffle Special Edition in poliertem Edelstahl (So werden Rockstars nun mal behandelt). Sogar der iPod shuffle Clip sieht stylish aus. Er klemmt sicher an Hemd, Jacke, Sportzeug oder am Rucksack. So wird der iPod shuffle zum perfekten Fashtech-Accessoire. Und klar, natürlich ist noch Platz für eine persönliche Gravur.

Mehrsprachig
Ein französisches Chanson. Ein spanischer Bolero. Eine italienische Arie. Dein Musikarchiv enthält Musik aus allen Ländern der Welt. Deshalb spricht VoiceOver 20 Sprachen und kann die Namen von Songs und Interpreten mit der richtigen Aussprache sprechen.
 
Zufall oder kein Zufall?
Der Schalter am iPod shuffle hat drei Einstellungen. Links wird deine Musik zufällig durcheinander gewürfelt. In der Mitte werden deine Songs in der normalen Reihenfolge gespielt. Rechts wird der iPod shuffle ausgeschaltet.
";2;False;0;;;Apple iPod shuffle Tragbarer MP3-Player 4 GB 3. Generation;apple-ipod-shuffle-2-gb-blau-2;True;True;P-1180;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;59.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40186,8361921296;39;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000578-apple-ipod-shuffle-4-gb-blau.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000579-apple-ipod-shuffle-4-gb-blau.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000580-apple-ipod-shuffle-4-gb-blau.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Apple iPod shuffle 2 GB grün;Apple iPod shuffle 2 GB grün;"
Apple iPod shuffle 2GB grün
 
 
Der kleinste iPod der Welt
 
 
Um den kleinsten iPod der Welt zu bauen, haben wir die Steuerung vom iPod shuffle in das Ohrhörerkabel integriert.
So wird der iPod shuffle noch kleiner und die Steuerung ist genau da, wo du sie einfach erreichst.
Wenn du einen Song abspielen, anhalten oder überspringen möchtest,
musst du nicht lange nach dem iPod shuffle suchen - greif einfach zum Kabel und drücke auf eine der Tasten.
Dieser Entertainment-Winzling sagt Ihnen auf Knopfdruck, welchen Titel er gerade abspielt
Organisieren Sie Ihre Musik in verschiedenen Wiedergabeslisten
Dank eines stabilen, integrierten Clips lässt sich der iPod shuffle fast überall befestigen.
Lassen Sie sich aufs Ungewisse ein: Verwenden Sie den Schalter für die Zufallswiedergabe,
um den Inhalt Ihres iPod shuffle neu zu mischen.
Lieferumfang: Apple Earphones mit Remote Fernbedienung
 
iPod shuffle - In leuchtenden neuen Farben spricht Musik dich richtig an
 
Der kleinste iPod der Welt
Um den kleinsten iPod der Welt zu bauen, haben wir die Steuerung vom iPod shuffle in das Ohrhörerkabel integriert. So wird der iPod shuffle noch kleiner und die Steuerung ist genau da, wo du sie einfach erreichst. Wenn du einen Song abspielen, anhalten oder überspringen möchtest, musst du nicht lange nach dem iPod shuffle suchen - greif einfach zum Kabel und drücke auf eine der Tasten.
 
Der erste iPod, der mit dir spricht
Die VoiceOver Funktion ist mit Sicherheit der nächste Hit auf dem iPod shuffle.1 Angenommen du hörst einen Song und willst wissen, wie er heißt oder von wem er ist: Einfach Knopf drücken und VoiceOver sagt es dir. Sogar die Namen deiner Wiedergabelisten verrät es dir. Und wenn die Batterie aufgeladen werden muss, sagt VoiceOver dir das auch.
 
Leichtbedienung
Die Steuerung befindet sich am Kabel des rechten Ohrstöpsels. Dadurch, dass die Steuerung jetzt hier angebracht ist, kannst du deine Musiktitel durchsuchen - und die VoiceOver Funktion aktivieren - ohne vom Joggen, Rad fahren oder anderen Aktivitäten abgelenkt zu werden. Der iPod shuffle wird mit dieser einfachen Steuerung geliefert. Du kannst aber auch Kopfhörer mit ähnlichen Bedienelementen von Herstellern wie Scosche, Klipsch, V-MODA und Belkin verwenden.
 

Dein Musikarchiv. Für unterwegs
Der iPod shuffle kommt jetzt mit 2 GB oder 4 GB. Mit dem 4 GB Modell hast du jede Menge Platz, um Musik für viele Stunden - bis zu 1.000 Songs - zu speichern.2 Damit bist du im Fitnessstudio oder auf dem Weg zur Arbeit bestens gerüstet. Außerdem kannst du jetzt mehrere Wiedergabelisten und auch Hörbücher verwenden.
 
Mehrere Wiedergabelisten
Wahrscheinlich hast du dir in iTunes schon einige Wiedergabelisten zusammengestellt. Eine für unterwegs. Eine fürs Fitnessstudio. Eine zum Chillen. Jetzt kannst du deine Wiedergabelisten auf dem Computer mit dem iPod shuffle synchronisieren und hast immer genau den richtigen Mix - egal, was du gerade machst oder in welcher Stimmung du bist. VoiceOver nennt dir den Namen jeder Wiedergabeliste. So kannst du ganz leicht zwischen ihnen wechseln und genau die auswählen, nach der dir gerade ist.
 
Farbe bekennen
Mit dem flachen, robusten Gehäuse aus eloxiertem Aluminium ist der iPod shuffle immer das passende Accessoire. In leuchtendem Pink, Blau, Grün, Schwarz oder Silber ist er ein echtes Fashion Statement. Ganz neu dabei: der iPod shuffle Special Edition in poliertem Edelstahl (So werden Rockstars nun mal behandelt). Sogar der iPod shuffle Clip sieht stylish aus. Er klemmt sicher an Hemd, Jacke, Sportzeug oder am Rucksack. So wird der iPod shuffle zum perfekten Fashtech-Accessoire. Und klar, natürlich ist noch Platz für eine persönliche Gravur.

Mehrsprachig
Ein französisches Chanson. Ein spanischer Bolero. Eine italienische Arie. Dein Musikarchiv enthält Musik aus allen Ländern der Welt. Deshalb spricht VoiceOver 20 Sprachen und kann die Namen von Songs und Interpreten mit der richtigen Aussprache sprechen.
 
Zufall oder kein Zufall?
Der Schalter am iPod shuffle hat drei Einstellungen. Links wird deine Musik zufällig durcheinander gewürfelt. In der Mitte werden deine Songs in der normalen Reihenfolge gespielt. Rechts wird der iPod shuffle ausgeschaltet.
";2;False;0;;;Apple iPod shuffle Tragbarer MP3-Player 4 GB 3. Generation;apple-ipod-shuffle-2-gb-gruen-2;True;True;P-1170;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;59.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40186,8328587963;39;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000584-apple-ipod-shuffle-4-gb-grun.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000579-apple-ipod-shuffle-4-gb-blau.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000580-apple-ipod-shuffle-4-gb-blau.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Apple iPod shuffle 2 GB silber;Apple iPod shuffle 2 GB silber;"
Apple iPod shuffle 2GB silber  
 
Der kleinste iPod der Welt
 
 
Um den kleinsten iPod der Welt zu bauen, haben wir die Steuerung vom iPod shuffle in das Ohrhörerkabel integriert.
So wird der iPod shuffle noch kleiner und die Steuerung ist genau da, wo du sie einfach erreichst.
Wenn du einen Song abspielen, anhalten oder überspringen möchtest,
musst du nicht lange nach dem iPod shuffle suchen - greif einfach zum Kabel und drücke auf eine der Tasten.
Dieser Entertainment-Winzling sagt Ihnen auf Knopfdruck, welchen Titel er gerade abspielt
Organisieren Sie Ihre Musik in verschiedenen Wiedergabeslisten
Dank eines stabilen, integrierten Clips lässt sich der iPod shuffle fast überall befestigen.
Lassen Sie sich aufs Ungewisse ein: Verwenden Sie den Schalter für die Zufallswiedergabe,
um den Inhalt Ihres iPod shuffle neu zu mischen.
Lieferumfang: Apple Earphones mit Remote Fernbedienung
 
iPod shuffle - In leuchtenden neuen Farben spricht Musik dich richtig an
 
Der kleinste iPod der Welt
Um den kleinsten iPod der Welt zu bauen, haben wir die Steuerung vom iPod shuffle in das Ohrhörerkabel integriert. So wird der iPod shuffle noch kleiner und die Steuerung ist genau da, wo du sie einfach erreichst. Wenn du einen Song abspielen, anhalten oder überspringen möchtest, musst du nicht lange nach dem iPod shuffle suchen - greif einfach zum Kabel und drücke auf eine der Tasten.
 
Der erste iPod, der mit dir spricht
Die VoiceOver Funktion ist mit Sicherheit der nächste Hit auf dem iPod shuffle.1 Angenommen du hörst einen Song und willst wissen, wie er heißt oder von wem er ist: Einfach Knopf drücken und VoiceOver sagt es dir. Sogar die Namen deiner Wiedergabelisten verrät es dir. Und wenn die Batterie aufgeladen werden muss, sagt VoiceOver dir das auch.
 
Leichtbedienung
Die Steuerung befindet sich am Kabel des rechten Ohrstöpsels. Dadurch, dass die Steuerung jetzt hier angebracht ist, kannst du deine Musiktitel durchsuchen - und die VoiceOver Funktion aktivieren - ohne vom Joggen, Rad fahren oder anderen Aktivitäten abgelenkt zu werden. Der iPod shuffle wird mit dieser einfachen Steuerung geliefert. Du kannst aber auch Kopfhörer mit ähnlichen Bedienelementen von Herstellern wie Scosche, Klipsch, V-MODA und Belkin verwenden.
 

Dein Musikarchiv. Für unterwegs
Der iPod shuffle kommt jetzt mit 2 GB oder 4 GB. Mit dem 4 GB Modell hast du jede Menge Platz, um Musik für viele Stunden - bis zu 1.000 Songs - zu speichern.2 Damit bist du im Fitnessstudio oder auf dem Weg zur Arbeit bestens gerüstet. Außerdem kannst du jetzt mehrere Wiedergabelisten und auch Hörbücher verwenden.
 
Mehrere Wiedergabelisten
Wahrscheinlich hast du dir in iTunes schon einige Wiedergabelisten zusammengestellt. Eine für unterwegs. Eine fürs Fitnessstudio. Eine zum Chillen. Jetzt kannst du deine Wiedergabelisten auf dem Computer mit dem iPod shuffle synchronisieren und hast immer genau den richtigen Mix - egal, was du gerade machst oder in welcher Stimmung du bist. VoiceOver nennt dir den Namen jeder Wiedergabeliste. So kannst du ganz leicht zwischen ihnen wechseln und genau die auswählen, nach der dir gerade ist.
 
Farbe bekennen
Mit dem flachen, robusten Gehäuse aus eloxiertem Aluminium ist der iPod shuffle immer das passende Accessoire. In leuchtendem Pink, Blau, Grün, Schwarz oder Silber ist er ein echtes Fashion Statement. Ganz neu dabei: der iPod shuffle Special Edition in poliertem Edelstahl (So werden Rockstars nun mal behandelt). Sogar der iPod shuffle Clip sieht stylish aus. Er klemmt sicher an Hemd, Jacke, Sportzeug oder am Rucksack. So wird der iPod shuffle zum perfekten Fashtech-Accessoire. Und klar, natürlich ist noch Platz für eine persönliche Gravur.

Mehrsprachig
Ein französisches Chanson. Ein spanischer Bolero. Eine italienische Arie. Dein Musikarchiv enthält Musik aus allen Ländern der Welt. Deshalb spricht VoiceOver 20 Sprachen und kann die Namen von Songs und Interpreten mit der richtigen Aussprache sprechen.
 
Zufall oder kein Zufall?
Der Schalter am iPod shuffle hat drei Einstellungen. Links wird deine Musik zufällig durcheinander gewürfelt. In der Mitte werden deine Songs in der normalen Reihenfolge gespielt. Rechts wird der iPod shuffle ausgeschaltet.
";2;False;0;;;Apple iPod shuffle Tragbarer MP3-Player 4 GB 3. Generation;apple-ipod-shuffle-2-gb-silber;True;True;P-1160;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;61.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40186,8309259259;39;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000220-apple-ipod-shuffle-4-gb-silber.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000221-apple-ipod-shuffle-4-gb-silber.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000222-apple-ipod-shuffle-4-gb-silber.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Apple iPod shuffle 4 GB schwarz;Apple iPod shuffle 4 GB schwarz;"
Apple iPod shuffle 4GB schwarz
 
 
Der kleinste iPod der Welt
 
 
Um den kleinsten iPod der Welt zu bauen, haben wir die Steuerung vom iPod shuffle in das Ohrhörerkabel integriert.
So wird der iPod shuffle noch kleiner und die Steuerung ist genau da, wo du sie einfach erreichst.
Wenn du einen Song abspielen, anhalten oder überspringen möchtest,
musst du nicht lange nach dem iPod shuffle suchen - greif einfach zum Kabel und drücke auf eine der Tasten.
Dieser Entertainment-Winzling sagt Ihnen auf Knopfdruck, welchen Titel er gerade abspielt
Organisieren Sie Ihre Musik in verschiedenen Wiedergabeslisten
Dank eines stabilen, integrierten Clips lässt sich der iPod shuffle fast überall befestigen.
Lassen Sie sich aufs Ungewisse ein: Verwenden Sie den Schalter für die Zufallswiedergabe,
um den Inhalt Ihres iPod shuffle neu zu mischen.
Lieferumfang: Apple Earphones mit Remote Fernbedienung
 
iPod shuffle - In leuchtenden neuen Farben spricht Musik dich richtig an
 
Der kleinste iPod der Welt
Um den kleinsten iPod der Welt zu bauen, haben wir die Steuerung vom iPod shuffle in das Ohrhörerkabel integriert. So wird der iPod shuffle noch kleiner und die Steuerung ist genau da, wo du sie einfach erreichst. Wenn du einen Song abspielen, anhalten oder überspringen möchtest, musst du nicht lange nach dem iPod shuffle suchen - greif einfach zum Kabel und drücke auf eine der Tasten.
 
Der erste iPod, der mit dir spricht
Die VoiceOver Funktion ist mit Sicherheit der nächste Hit auf dem iPod shuffle.1 Angenommen du hörst einen Song und willst wissen, wie er heißt oder von wem er ist: Einfach Knopf drücken und VoiceOver sagt es dir. Sogar die Namen deiner Wiedergabelisten verrät es dir. Und wenn die Batterie aufgeladen werden muss, sagt VoiceOver dir das auch.
 
Leichtbedienung
Die Steuerung befindet sich am Kabel des rechten Ohrstöpsels. Dadurch, dass die Steuerung jetzt hier angebracht ist, kannst du deine Musiktitel durchsuchen - und die VoiceOver Funktion aktivieren - ohne vom Joggen, Rad fahren oder anderen Aktivitäten abgelenkt zu werden. Der iPod shuffle wird mit dieser einfachen Steuerung geliefert. Du kannst aber auch Kopfhörer mit ähnlichen Bedienelementen von Herstellern wie Scosche, Klipsch, V-MODA und Belkin verwenden.
 

Dein Musikarchiv. Für unterwegs
Der iPod shuffle kommt jetzt mit 2 GB oder 4 GB. Mit dem 4 GB Modell hast du jede Menge Platz, um Musik für viele Stunden - bis zu 1.000 Songs - zu speichern.2 Damit bist du im Fitnessstudio oder auf dem Weg zur Arbeit bestens gerüstet. Außerdem kannst du jetzt mehrere Wiedergabelisten und auch Hörbücher verwenden.
 
Mehrere Wiedergabelisten
Wahrscheinlich hast du dir in iTunes schon einige Wiedergabelisten zusammengestellt. Eine für unterwegs. Eine fürs Fitnessstudio. Eine zum Chillen. Jetzt kannst du deine Wiedergabelisten auf dem Computer mit dem iPod shuffle synchronisieren und hast immer genau den richtigen Mix - egal, was du gerade machst oder in welcher Stimmung du bist. VoiceOver nennt dir den Namen jeder Wiedergabeliste. So kannst du ganz leicht zwischen ihnen wechseln und genau die auswählen, nach der dir gerade ist.
 
Farbe bekennen
Mit dem flachen, robusten Gehäuse aus eloxiertem Aluminium ist der iPod shuffle immer das passende Accessoire. In leuchtendem Pink, Blau, Grün, Schwarz oder Silber ist er ein echtes Fashion Statement. Ganz neu dabei: der iPod shuffle Special Edition in poliertem Edelstahl (So werden Rockstars nun mal behandelt). Sogar der iPod shuffle Clip sieht stylish aus. Er klemmt sicher an Hemd, Jacke, Sportzeug oder am Rucksack. So wird der iPod shuffle zum perfekten Fashtech-Accessoire. Und klar, natürlich ist noch Platz für eine persönliche Gravur.

Mehrsprachig
Ein französisches Chanson. Ein spanischer Bolero. Eine italienische Arie. Dein Musikarchiv enthält Musik aus allen Ländern der Welt. Deshalb spricht VoiceOver 20 Sprachen und kann die Namen von Songs und Interpreten mit der richtigen Aussprache sprechen.
 
Zufall oder kein Zufall?
Der Schalter am iPod shuffle hat drei Einstellungen. Links wird deine Musik zufällig durcheinander gewürfelt. In der Mitte werden deine Songs in der normalen Reihenfolge gespielt. Rechts wird der iPod shuffle ausgeschaltet.
";2;False;0;;;Apple iPod shuffle Tragbarer MP3-Player 4 GB 3. Generation;apple-ipod-shuffle-4-gb-schwarz;True;True;P-1240;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;79.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40186,8276273148;40;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000585-apple-ipod-shuffle-4-gb-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000586-apple-ipod-shuffle-4-gb-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000587-apple-ipod-shuffle-4-gb-schwarz.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Apple iPod shuffle 4 GB grün;Apple iPod shuffle 4 GB grün;"
Apple iPod shuffle 4GB grün
 
 
Der kleinste iPod der Welt
 
 
Um den kleinsten iPod der Welt zu bauen, haben wir die Steuerung vom iPod shuffle in das Ohrhörerkabel integriert.
So wird der iPod shuffle noch kleiner und die Steuerung ist genau da, wo du sie einfach erreichst.
Wenn du einen Song abspielen, anhalten oder überspringen möchtest,
musst du nicht lange nach dem iPod shuffle suchen - greif einfach zum Kabel und drücke auf eine der Tasten.
Dieser Entertainment-Winzling sagt Ihnen auf Knopfdruck, welchen Titel er gerade abspielt
Organisieren Sie Ihre Musik in verschiedenen Wiedergabeslisten
Dank eines stabilen, integrierten Clips lässt sich der iPod shuffle fast überall befestigen.
Lassen Sie sich aufs Ungewisse ein: Verwenden Sie den Schalter für die Zufallswiedergabe,
um den Inhalt Ihres iPod shuffle neu zu mischen.
Lieferumfang: Apple Earphones mit Remote Fernbedienung
 
iPod shuffle - In leuchtenden neuen Farben spricht Musik dich richtig an
 
Der kleinste iPod der Welt
Um den kleinsten iPod der Welt zu bauen, haben wir die Steuerung vom iPod shuffle in das Ohrhörerkabel integriert. So wird der iPod shuffle noch kleiner und die Steuerung ist genau da, wo du sie einfach erreichst. Wenn du einen Song abspielen, anhalten oder überspringen möchtest, musst du nicht lange nach dem iPod shuffle suchen - greif einfach zum Kabel und drücke auf eine der Tasten.
 
Der erste iPod, der mit dir spricht
Die VoiceOver Funktion ist mit Sicherheit der nächste Hit auf dem iPod shuffle.1 Angenommen du hörst einen Song und willst wissen, wie er heißt oder von wem er ist: Einfach Knopf drücken und VoiceOver sagt es dir. Sogar die Namen deiner Wiedergabelisten verrät es dir. Und wenn die Batterie aufgeladen werden muss, sagt VoiceOver dir das auch.
 
Leichtbedienung
Die Steuerung befindet sich am Kabel des rechten Ohrstöpsels. Dadurch, dass die Steuerung jetzt hier angebracht ist, kannst du deine Musiktitel durchsuchen - und die VoiceOver Funktion aktivieren - ohne vom Joggen, Rad fahren oder anderen Aktivitäten abgelenkt zu werden. Der iPod shuffle wird mit dieser einfachen Steuerung geliefert. Du kannst aber auch Kopfhörer mit ähnlichen Bedienelementen von Herstellern wie Scosche, Klipsch, V-MODA und Belkin verwenden.
 

Dein Musikarchiv. Für unterwegs
Der iPod shuffle kommt jetzt mit 2 GB oder 4 GB. Mit dem 4 GB Modell hast du jede Menge Platz, um Musik für viele Stunden - bis zu 1.000 Songs - zu speichern.2 Damit bist du im Fitnessstudio oder auf dem Weg zur Arbeit bestens gerüstet. Außerdem kannst du jetzt mehrere Wiedergabelisten und auch Hörbücher verwenden.
 
Mehrere Wiedergabelisten
Wahrscheinlich hast du dir in iTunes schon einige Wiedergabelisten zusammengestellt. Eine für unterwegs. Eine fürs Fitnessstudio. Eine zum Chillen. Jetzt kannst du deine Wiedergabelisten auf dem Computer mit dem iPod shuffle synchronisieren und hast immer genau den richtigen Mix - egal, was du gerade machst oder in welcher Stimmung du bist. VoiceOver nennt dir den Namen jeder Wiedergabeliste. So kannst du ganz leicht zwischen ihnen wechseln und genau die auswählen, nach der dir gerade ist.
 
Farbe bekennen
Mit dem flachen, robusten Gehäuse aus eloxiertem Aluminium ist der iPod shuffle immer das passende Accessoire. In leuchtendem Pink, Blau, Grün, Schwarz oder Silber ist er ein echtes Fashion Statement. Ganz neu dabei: der iPod shuffle Special Edition in poliertem Edelstahl (So werden Rockstars nun mal behandelt). Sogar der iPod shuffle Clip sieht stylish aus. Er klemmt sicher an Hemd, Jacke, Sportzeug oder am Rucksack. So wird der iPod shuffle zum perfekten Fashtech-Accessoire. Und klar, natürlich ist noch Platz für eine persönliche Gravur.

Mehrsprachig
Ein französisches Chanson. Ein spanischer Bolero. Eine italienische Arie. Dein Musikarchiv enthält Musik aus allen Ländern der Welt. Deshalb spricht VoiceOver 20 Sprachen und kann die Namen von Songs und Interpreten mit der richtigen Aussprache sprechen.
 
Zufall oder kein Zufall?
Der Schalter am iPod shuffle hat drei Einstellungen. Links wird deine Musik zufällig durcheinander gewürfelt. In der Mitte werden deine Songs in der normalen Reihenfolge gespielt. Rechts wird der iPod shuffle ausgeschaltet.
 
";2;False;0;;;Apple iPod shuffle Tragbarer MP3-Player 4 GB 3. Generation;apple-ipod-shuffle-4-gb-gruen;True;True;P-1230;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;77.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40186,8252662037;40;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000584-apple-ipod-shuffle-4-gb-grun.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000579-apple-ipod-shuffle-4-gb-blau.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000580-apple-ipod-shuffle-4-gb-blau.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Apple iPod shuffle 4 GB blau;Apple iPod shuffle 4GB blau;"
Apple iPod shuffle 4GB blau
 
 
Der kleinste iPod der Welt
 
 
Um den kleinsten iPod der Welt zu bauen, haben wir die Steuerung vom iPod shuffle in das Ohrhörerkabel integriert.
So wird der iPod shuffle noch kleiner und die Steuerung ist genau da, wo du sie einfach erreichst.
Wenn du einen Song abspielen, anhalten oder überspringen möchtest,
musst du nicht lange nach dem iPod shuffle suchen - greif einfach zum Kabel und drücke auf eine der Tasten.
Dieser Entertainment-Winzling sagt Ihnen auf Knopfdruck, welchen Titel er gerade abspielt
Organisieren Sie Ihre Musik in verschiedenen Wiedergabeslisten
Dank eines stabilen, integrierten Clips lässt sich der iPod shuffle fast überall befestigen.
Lassen Sie sich aufs Ungewisse ein: Verwenden Sie den Schalter für die Zufallswiedergabe,
um den Inhalt Ihres iPod shuffle neu zu mischen.
Lieferumfang: Apple Earphones mit Remote Fernbedienung
 
iPod shuffle - In leuchtenden neuen Farben spricht Musik dich richtig an
 
Der kleinste iPod der Welt
Um den kleinsten iPod der Welt zu bauen, haben wir die Steuerung vom iPod shuffle in das Ohrhörerkabel integriert. So wird der iPod shuffle noch kleiner und die Steuerung ist genau da, wo du sie einfach erreichst. Wenn du einen Song abspielen, anhalten oder überspringen möchtest, musst du nicht lange nach dem iPod shuffle suchen - greif einfach zum Kabel und drücke auf eine der Tasten.
 
Der erste iPod, der mit dir spricht
Die VoiceOver Funktion ist mit Sicherheit der nächste Hit auf dem iPod shuffle.1 Angenommen du hörst einen Song und willst wissen, wie er heißt oder von wem er ist: Einfach Knopf drücken und VoiceOver sagt es dir. Sogar die Namen deiner Wiedergabelisten verrät es dir. Und wenn die Batterie aufgeladen werden muss, sagt VoiceOver dir das auch.
 
Leichtbedienung
Die Steuerung befindet sich am Kabel des rechten Ohrstöpsels. Dadurch, dass die Steuerung jetzt hier angebracht ist, kannst du deine Musiktitel durchsuchen - und die VoiceOver Funktion aktivieren - ohne vom Joggen, Rad fahren oder anderen Aktivitäten abgelenkt zu werden. Der iPod shuffle wird mit dieser einfachen Steuerung geliefert. Du kannst aber auch Kopfhörer mit ähnlichen Bedienelementen von Herstellern wie Scosche, Klipsch, V-MODA und Belkin verwenden.
 

Dein Musikarchiv. Für unterwegs
Der iPod shuffle kommt jetzt mit 2 GB oder 4 GB. Mit dem 4 GB Modell hast du jede Menge Platz, um Musik für viele Stunden - bis zu 1.000 Songs - zu speichern.2 Damit bist du im Fitnessstudio oder auf dem Weg zur Arbeit bestens gerüstet. Außerdem kannst du jetzt mehrere Wiedergabelisten und auch Hörbücher verwenden.
 
Mehrere Wiedergabelisten
Wahrscheinlich hast du dir in iTunes schon einige Wiedergabelisten zusammengestellt. Eine für unterwegs. Eine fürs Fitnessstudio. Eine zum Chillen. Jetzt kannst du deine Wiedergabelisten auf dem Computer mit dem iPod shuffle synchronisieren und hast immer genau den richtigen Mix - egal, was du gerade machst oder in welcher Stimmung du bist. VoiceOver nennt dir den Namen jeder Wiedergabeliste. So kannst du ganz leicht zwischen ihnen wechseln und genau die auswählen, nach der dir gerade ist.
 
Farbe bekennen
Mit dem flachen, robusten Gehäuse aus eloxiertem Aluminium ist der iPod shuffle immer das passende Accessoire. In leuchtendem Pink, Blau, Grün, Schwarz oder Silber ist er ein echtes Fashion Statement. Ganz neu dabei: der iPod shuffle Special Edition in poliertem Edelstahl (So werden Rockstars nun mal behandelt). Sogar der iPod shuffle Clip sieht stylish aus. Er klemmt sicher an Hemd, Jacke, Sportzeug oder am Rucksack. So wird der iPod shuffle zum perfekten Fashtech-Accessoire. Und klar, natürlich ist noch Platz für eine persönliche Gravur.

Mehrsprachig
Ein französisches Chanson. Ein spanischer Bolero. Eine italienische Arie. Dein Musikarchiv enthält Musik aus allen Ländern der Welt. Deshalb spricht VoiceOver 20 Sprachen und kann die Namen von Songs und Interpreten mit der richtigen Aussprache sprechen.
 
Zufall oder kein Zufall?
Der Schalter am iPod shuffle hat drei Einstellungen. Links wird deine Musik zufällig durcheinander gewürfelt. In der Mitte werden deine Songs in der normalen Reihenfolge gespielt. Rechts wird der iPod shuffle ausgeschaltet.
";2;False;0;;;Apple iPod shuffle Tragbarer MP3-Player 4 GB 3. Generation;apple-ipod-shuffle-4-gb-blau;True;True;P-1220;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;77.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40186,8199537037;40;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000578-apple-ipod-shuffle-4-gb-blau.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000579-apple-ipod-shuffle-4-gb-blau.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000580-apple-ipod-shuffle-4-gb-blau.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Canon EOS 1000D SLR-Digitalkamera Kit;"Canon EOS 1000D SLR-Digitalkamera Kit inkl. EF-S 18-55 Objektiv ";"
Canon EOS 1000D:Anpfiff für den Aufstieg
 
Wer bislang mit der digitalen Spiegelreflexfotografie nur geliebäugelt hat, wird dieser Canon-Neuheit nur schwerlich widerstehen können: EOS 1000D heißt die neue Kamera. Die Neue punktet mit einem Preis-Leistungsverhältnis, das eine neue Canon- Liga kennzeichnet: 10,1 Megapixel CMOS-Sensor, Sieben-Punkt-Weitbereich- Autofokus und Reihenaufnahmen mit bis zu drei JPEG-komprimierten Bildern pro Sekunde. Die Marke, der die Profis vertrauen, ist also jetzt auch für den Einsteiger in die digitale Spiegelreflexfotografie erschwinglich… und dank benutzerfreundlicher Menüführung auch leicht bedienbar.
 
Die EOS 1000D ist die bislang leichteste aller digitalen EOS-Kameras und basiert auf intuitiver Bedienung und einer Reihe von innovativen Spitzentechnologien, die auch in der professionellen Serie der Canon EOS-1 Kameras zum Einsatz kommen. Dies sind beispielsweise der DIGIC-III-Bildprozessor, Livebild-Funktion und EOSIntegrated- Cleaning-System, das integrierte Sensor-Reinigungsprogramm von Canon. Die EOS 1000D gibt es auch im kostengünstigen Paket mit dem Objektiv EF-S 18- 55mm IS: Dieses Canon-Objektiv hat einen optischen Bildstabilisator, der eine längere Belichtungszeit erlaubt, weil diese Technologie Verwacklungen entgegenwirkt. Das zahlt sich besonders bei schlechten Lichtverhältnissen aus.
Intelligenter Fokus und Blitz

Bei dynamischen Aufnahmesituationen ist eine schnelle Fokussierung sehr wichtig – hier macht sich der Sieben-Punkt-Weitbereich-Autofokus der EOS 1000D durch die Scharfstellung in Sekundenbruchteilen bezahlt. Das zentrale AF-Messfeld ist ein Kreuzsensor, der sich vor allem in Aufnahmesituationen mit wenig Licht beziehungsweise schwach ausgeprägtem Kontrast bewährt. Hinzu kommt ein weiteres von den professionellen EOS-Modellen bekanntes Leistungsmerkmal: das entfernungsgekoppelte Blitzsteuerungssystem E-TTL II.
 
Konzipiert für mehr Leistung
Wie bei allen EOS-Modellen werden auch die Kernelemente der EOS 1000D von Canon selbst konzipiert und gefertigt, eine Kombination für bestmögliche Bildqualität. Der 10,1 Megapixel CMOS-Sensor sorgt für präzise, rauscharme Bilder und bietet mehr als genug Auflösung für den Fotodruck bis DIN A4. Zum Schutz vor störenden Staubpartikeln ist der Sensor der Neuen mit dem bekannten EOS Integrated Cleaning System ausgestattet, das den Staub in drei separaten Schritten bekämpft: reduzieren, abweisen und entfernen.
Die EOS 1000D verfügt mit dem DIGIC III über einen Bildprozessor, der auch bei den professionellen digitalen Canon-Spiegelreflexkameras zum Einsatz kommt. Dies ermöglicht kontinuierliche Reihenaufnahmen bis zur Kapazitätsgrenze der jeweilig eingesetzten SD- oder SDHC-Speicherkarte bei Geschwindigkeiten von bis zu drei Bildern pro Sekunde. Darüber hinaus ist der DIGIC-III-Prozessor für hochwertige Bildwiedergabe, schnelle Signalverarbeitung und nahezu umgehende Startzeiten verantwortlich.
 
 
Hoher Anwenderkomfort
Mit gerade einmal 450 Gramm (nur Gehäuse) ist die EOS 1000D die bislang leichteste digitale Canon Spiegelreflexkamera von Canon. Das kompakte, ergonomisch gestaltete Gehäuse ist konsequent auf effiziente Handhabung ausgelegt.^ Auf dem hellen 2,5 Zoll großen LC-Monitor lassen sich die Bilder umgehend überprüfen oder auch – dank des weiten Betrachtungswinkels – von mehreren Personen gleichzeitig einsehen. Ferner bietet das LC-Display Zugriff auf eine intuitive, leicht verständliche Menüstruktur mit praktischen Reitern – das ist übersichtlich und erleichtert das Auffinden von Menüpunkten.
 
Live View
Bei Aufnahmen vom Stativ oder wenn sich der Sucher als unpraktisch erweist, ermöglicht die Livebild-Funktion die Kontrolle des Motivs über das Display. Dabei wird das Livebild als Videosequenz mit 30 Bildern pro Sekunde dargestellt. Zur Beurteilung von Bildkomposition oder Belichtungseinstellung lassen sich Gitternetzlinien oder ein Histogramm einblenden. Für die Livebild-Funktion stehen zwei AF-Modi zur Verfügung: Quick AF, der zur Aktivierung des AF-Sensors umgehend den Kameraspiegel hochklappt und Live AF, der Kontrastinformationen für die Scharfstellung wie bei einer Kompaktkamera einsetzt.
 
Software
Zum Lieferumfang der EOS 1000D gehört ein umfassendes Softwarepaket mit den notwendigen Tools zur Bearbeitung und Verwaltung der Bilder. Zum Beispiel Digital Photo Professional (DPP), ein leistungsstarkes Programm zur Bearbeitung von RAWBildern. DPP bewährt sich auch im Zusammenspiel mit Kamerafunktionen wie Dust Delete Data und Picture Styles. Die im Lieferumfang enthaltene Software Picture Style Editor kann eingesetzt werden, um individuelle Picture Styles für die Feinabstimmung von Farben zu erstellen. Weitere mitgelieferte Softwareanwendungen sind EOS Utility, Image/Zoom Browser und Photostitch. 
 
EF-S 18-55 Objektiv
Speziell für digitale EOS Kameras mit EF-S-Bjonett entwickeltes Standard-Zoom
Kompakt und leicht
Hohe Bildqualität bei allen Brennweiten
Optimierte Vergütungsschichten minimieren Streulicht und Reflexe
Hohe AF-Geschwindigkeit
Sehr kurze Naheinstellgrenze
Bleifreie Optik
";2;False;0;;;"Canon EOS 1000D SLR-Digitalkamera Kit inkl. EF-S 18-55 Objektiv ";canon-eos-1000d-slr-digitalkamera-kit;True;True;P-1740;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;429.0000;0.0000;409.9000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40166,6718402778;"56;2095";25;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000481-canon-eos-1000d-slr-digitalkamera-kit.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000482-canon-eos-1000d-slr-digitalkamera-kit.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000483-canon-eos-1000d-slr-digitalkamera-kit.jpg;1;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Sandisk Sansa Fuze 8 GB schwarz;"Sandisk Sansa Fuze MP3-/Video-Player 8 GB mit Radio schwarz ";"

Sandisk Sansa Fuze MP3-/Video-Player 8 GB mit Radio schwarz

 
Mit der verfügbaren Akkuleistung können Sie 24 Stunden lang Musik hören, Bilder anschauen oder spielen.
Der neue Sansa Fuze von SanDisk ist der ideale tragbare Musikplayer für Sie.
Er steht mit einer Speicherkapazität 4 GB in schwarz,rot,pink zur Verfügung.
Sehen Sie sich Ihre Lieblingsvideoclips auf dem 1,9""-Farbdisplay des Sansa Fuze an.
Lauschen Sie dem FM-Radio mit 40 voreingestellten Sendern oder probieren Sie den integrierten Sprachrekorder aus. Mit einer unglaublich starken Akkuleistung in einem 0,3"" schmalen Gerät setzt der Sansa Fuze Zeichen.
";2;False;0;;;Sandisk Sansa Fuze MP3-/Video-Player 4 GB mit Radio;sandisk-sansa-fuze-8-gb-schwarz;True;True;P-1600;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;89.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40166,6556365741;52;8;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000480-sandisk-sansa-fuze-8-gb-schwarz.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Apple iPod shuffle 1 GB blau;Apple iPod shuffle 1 GB blau;"

Apple iPod shuffle 1GB blue 

 
Wie seine größeren Geschwister besitzt auch der iPod shuffle kreisförmig
angeordnete, ergonomische Bedienelemente.
Der Kopfhöreranschluss am iPod shuffle dient gleichzeitig als Dock-Anschluss.
Drehen Sie den iPod shuffle auf die Seite und setzen Sie ihn in das mitgelieferte Dock ein.
Dank eines stabilen, integrierten Clips lässt sich der iPod shuffle fast überall befestigen.
Klemmen Sie ihn am T-Shirt, am Hemdkragen oder am Trageriemen von Rucksack oder Handtasche fest.
Lassen Sie sich aufs Ungewisse ein: Verwenden Sie den Schalter für die Zufallswiedergabe,
um den Inhalt Ihres iPod shuffle neu zu mischen.
verbesserte Kopfhörer und das neue iTunes 8.0
 
Größe ist relativ
Natürlich kennen Sie das Sprichwort ""Weniger ist mehr"". Wie wahr dieses Sprichwort ist, beweist der neue iPod shuffle, der gerade einmal 4,1 cm lang ist, nur etwa 15 Gramm wiegt und Platz für bis zu 240 Songs bietet. Hinzu kommt, dass Sie Ihre Musik damit bis zu 12 Stunden lang ohne Unterbrechung hören können.(2) Man kann also mit Fug und Recht behaupten, dass der winzige iPod shuffle bei halber Größe viel mehr zu bieten hat, als man ihm auf den ersten Blick zutraut.
Immer im Trend
Klemmen Sie ihn an die Jeans. Oder an Ihre Handtasche. Egal, wo Sie ihn anklippen, mit Ihrem iPod shuffle haben Sie Ihre Musik jederzeit griffbereit. Das Gehäuse aus eloxiertem Aluminium passt übrigens zu jedem Outfit. Einfach festklemmen und einschalten - Sie werden ohne Zweifel viele begehrliche Blicke auf sich ziehen.
 
 
Perfekt synchronisiert
Damit Sie Ihren iPod shuffle mit bis zu 240 Songs füllen können, müssen Sie zuerst iTunes gratis laden. Danach können Sie für je 99 Cent Musiktitel aus dem iTunes Store laden oder von Ihren CDs importieren. Zum Synchronisieren schließen Sie das mitgelieferte Dock an den USB-Anschluss Ihres Mac oder PC an und übertragen die Musik aus iTunes, indem Sie den iPod shuffle in das Dock einsetzen.
 
 
Neu abgemischt
In Ihrer iTunes Bibliothek befinden sich mehr als 240 Titel? Kein Problem. Überlassen Sie es iTunes, Ihren iPod shuffle automatisch zu füllen und genießen Sie Ihre Musik jedes Mal neu. Pop folgt auf Jazz, Rock auf Ra!

 
";2;False;0;;;Apple iPod shuffle 1 GB blau;apple-ipod-shuffle-1-gb-blau;True;True;P-1110;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;49.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40160,8793055556;36;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000398-apple-ipod-shuffle-2-gb-blau.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000399-apple-ipod-shuffle-2-gb-blau.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000400-apple-ipod-shuffle-2-gb-blau.jpg;3;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Apple iPod shuffle 1 GB pink;Apple iPod shuffle 1 GB pink;"

Apple iPod shuffle 1GB pink 

 
Wie seine größeren Geschwister besitzt auch der iPod shuffle
kreisförmig angeordnete, ergonomische Bedienelemente.
Der Kopfhöreranschluss am iPod shuffle dient gleichzeitig als Dock-Anschluss.
Drehen Sie den iPod shuffle auf die Seite und setzen Sie ihn in das mitgelieferte Dock ein.
Dank eines stabilen, integrierten Clips lässt sich der iPod shuffle fast überall befestigen.
Klemmen Sie ihn am T-Shirt, am Hemdkragen oder am Trageriemen von Rucksack oder Handtasche fest.
Lassen Sie sich aufs Ungewisse ein: Verwenden Sie den Schalter für die Zufallswiedergabe,
um den Inhalt Ihres iPod shuffle neu zu mischen.
verbesserte Kopfhörer und das neue iTunes 8.0
 
Größe ist relativ
Natürlich kennen Sie das Sprichwort ""Weniger ist mehr"". Wie wahr dieses Sprichwort ist, beweist der neue iPod shuffle, der gerade einmal 4,1 cm lang ist, nur etwa 15 Gramm wiegt und Platz für bis zu 240 Songs bietet. Hinzu kommt, dass Sie Ihre Musik damit bis zu 12 Stunden lang ohne Unterbrechung hören können.(2) Man kann also mit Fug und Recht behaupten, dass der winzige iPod shuffle bei halber Größe viel mehr zu bieten hat, als man ihm auf den ersten Blick zutraut.
Immer im Trend
Klemmen Sie ihn an die Jeans. Oder an Ihre Handtasche. Egal, wo Sie ihn anklippen, mit Ihrem iPod shuffle haben Sie Ihre Musik jederzeit griffbereit. Das Gehäuse aus eloxiertem Aluminium passt übrigens zu jedem Outfit. Einfach festklemmen und einschalten - Sie werden ohne Zweifel viele begehrliche Blicke auf sich ziehen.
 
 
Perfekt synchronisiert
Damit Sie Ihren iPod shuffle mit bis zu 240 Songs füllen können, müssen Sie zuerst iTunes gratis laden. Danach können Sie für je 99 Cent Musiktitel aus dem iTunes Store laden oder von Ihren CDs importieren. Zum Synchronisieren schließen Sie das mitgelieferte Dock an den USB-Anschluss Ihres Mac oder PC an und übertragen die Musik aus iTunes, indem Sie den iPod shuffle in das Dock einsetzen.
 
 
Neu abgemischt
In Ihrer iTunes Bibliothek befinden sich mehr als 240 Titel? Kein Problem. Überlassen Sie es iTunes, Ihren iPod shuffle automatisch zu füllen und genießen Sie Ihre Musik jedes Mal neu. Pop folgt auf Jazz, Rock auf Ra!
";2;False;0;;;Apple iPod shuffle 1GB pink;apple-ipod-shuffle-1-gb-pink;True;True;P-1120;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;49.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40158,9546990741;36;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000118-apple-ipod-shuffle-2-gb-pink.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000119-apple-ipod-shuffle-2-gb-pink.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000120-apple-ipod-shuffle-2-gb-pink.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Apple iPod shuffle 1 GB grün;Apple iPod shuffle 1 GB grün;"
Apple iPod shuffle 1GB grün

 
Wie seine größeren Geschwister besitzt auch der iPod shuffle kreisförmig angeordnete, ergonomische Bedienelemente.
Der Kopfhöreranschluss am iPod shuffle dient gleichzeitig als Dock-Anschluss.
Drehen Sie den iPod shuffle auf die Seite und setzen Sie ihn in das mitgelieferte Dock ein.
Dank eines stabilen, integrierten Clips lässt sich der iPod shuffle fast überall befestigen.
Klemmen Sie ihn am T-Shirt, am Hemdkragen oder am Trageriemen von Rucksack oder Handtasche fest.
Lassen Sie sich aufs Ungewisse ein: Verwenden Sie den Schalter für die Zufallswiedergabe, um den Inhalt Ihres iPod shuffle neu zu mischen.
verbesserte Kopfhörer und das neue iTunes 8.0
 
Größe ist relativ
Natürlich kennen Sie das Sprichwort ""Weniger ist mehr"". Wie wahr dieses Sprichwort ist, beweist der neue iPod shuffle, der gerade einmal 4,1 cm lang ist, nur etwa 15 Gramm wiegt und Platz für bis zu 240 Songs bietet. Hinzu kommt, dass Sie Ihre Musik damit bis zu 12 Stunden lang ohne Unterbrechung hören können.(2) Man kann also mit Fug und Recht behaupten, dass der winzige iPod shuffle bei halber Größe viel mehr zu bieten hat, als man ihm auf den ersten Blick zutraut.
Immer im Trend
Klemmen Sie ihn an die Jeans. Oder an Ihre Handtasche. Egal, wo Sie ihn anklippen, mit Ihrem iPod shuffle haben Sie Ihre Musik jederzeit griffbereit. Das Gehäuse aus eloxiertem Aluminium passt übrigens zu jedem Outfit. Einfach festklemmen und einschalten - Sie werden ohne Zweifel viele begehrliche Blicke auf sich ziehen.
 
 
Perfekt synchronisiert
Damit Sie Ihren iPod shuffle mit bis zu 240 Songs füllen können, müssen Sie zuerst iTunes gratis laden. Danach können Sie für je 99 Cent Musiktitel aus dem iTunes Store laden oder von Ihren CDs importieren. Zum Synchronisieren schließen Sie das mitgelieferte Dock an den USB-Anschluss Ihres Mac oder PC an und übertragen die Musik aus iTunes, indem Sie den iPod shuffle in das Dock einsetzen.
 
 
Neu abgemischt
In Ihrer iTunes Bibliothek befinden sich mehr als 240 Titel? Kein Problem. Überlassen Sie es iTunes, Ihren iPod shuffle automatisch zu füllen und genießen Sie Ihre Musik jedes Mal neu. Pop folgt auf Jazz, Rock auf Ra!
";2;False;0;;;Apple iPod shuffle 1 GB grün;apple-ipod-shuffle-1-gb-gruen;True;True;P-1100;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;49.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40158,9517476852;36;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000429-apple-ipod-shuffle-2-gb-grun.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000430-apple-ipod-shuffle-2-gb-grun.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000431-apple-ipod-shuffle-2-gb-grun.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Panasonic DMR EX 72 SEG DVD HDD RECORDER;Panasonic DMR EX 72 SEG DVD- und HDD-Rekorder 160 GB;"

Panasonic DMR EX 72 SEG DVD- und HDD-Rekorder 160 GB

mit integriertem DVB-S Tuner
 
HDD/DVD Recorder/Farbe: schwarz/ Festplattenspeicher: 160 GB/ Tuner: DVB-S/ Sonderfunktionen: EPG/ Anschlüsse: 2x Scart, 3x Cinch (Komponenten/YUV),
Cinch (Composite / Video / FBas), HDMI (mit HDCP), S-Video (Hosiden), USB/ B: 430 mm/ H: 59 mm
Art HDD/DVD Recorder
Farbe schwarz
Festplattenspeicher 160 GB
Tuner DVB-S
Sonderfunktionen EPG
Anschlüsse 2x Scart / 3x Cinch (Komponenten/YUV) / Cinch (Composite / Video / FBas) / HDMI (mit HDCP) / S-Video (Hosiden) / USB
Breite 430 mm
Höhe   59 mm
Tiefe  286 mm
Gewicht netto 3,7 kg
Aufnahme DVD+R / DVD+RW / DVD-R / DVD-RAM / DVD-RW
Wiedergabe Audio-CD / CD-R / CD-RW / DVD / DVD+R / DVD+RW / DVD-R / DVD-RAM / DVD-RW / JPEG / MP3 / S-Video CD / WMA
";2;False;0;;;Panasonic DMR EX 72 SEG DVD HDD RECORDER;panasonic-dmr-ex-72-seg-dvd-hdd-recorder;True;True;P-1850;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;399.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40155,86625;62;12;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000471-panasonic-dmr-ex-72-seg-dvd-hdd-recorder.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000472-panasonic-dmr-ex-72-seg-dvd-hdd-recorder.jpg;;1;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Panasonic DMR EH 495 EG K 160 GB DVD/ HDD Rekorder;Panasonic DMR EH 495 EG K 160 GB DVD/ HDD Rekorder;"
Panasonic DMR EH 495 EG K 160 GB DVD/ HDD Rekorder

HDMI, DivX-zertifiziert, USB 2.0

Mit dem DMR-EH495 präsentiert Panasonic, Marktführer bei DVD-Rekordern, neue Multiformat-DVD-Festplatten-Kombinationen. Sie bieten alle Komfortmerkmale der testbewährten Vorjahresmodelle, begeistern mit noch mehr Details sowie einer intuitiven Benutzerführung. Die mit einem analogen Tuner ausgestatteten Geräte verfügen über eine integrierte Festplatte und zeichnen auf alle gängigen DVD-Formate auf. Neben der Aufnahme des Fernsehprogramms überzeugen die neuen Rekorder als digitales Fotoalbum sowie Musik-Jukebox und werden somit zur Unterhaltungszentrale im Wohnzimmer. Komfortfunktionen wie der elektronische Programmführer Guide Plus+ mit Suchfunktion, eine automatische Kapitelerstellung, umfangreiche Anschlussmöglichkeiten sowie ein hochwertiger Upscaler machen die Rekorder zu Multitalenten. Darüber hinaus schont der weiterentwickelte Eco-Modus Umwelt und Geldbeutel.
 
Die Rekorder DMR-EH495 zeigen sich als wahre Alleskönner und zeichnen auf Festplatte oder DVD auf.
Sie verarbeiten alle gängigen DVD-Formate wie DVD-RW, -R (DL), DVD+RW/+R (DL) sowie DVD-RAM. Außerdem können CDs, CD-R/-RWs sowie MP3- und JPEG-Daten sowohl von DVD als auch CD abgespielt werden.
Die integrierte Festplatte erlaubt die Aufzeichnung von Fernsehprogrammen. Somit ist auch bei längerer Abwesenheit genügend Platz für die Lieblingsserie vorhanden.
Dank des integrierten, elektronischen Programmführers Gemstar Guide Plus+ erfolgen die Programmauswahl und Timerprogrammierung kinderleicht und intuitiv.
Die übersichtliche Darstellung des Fernsehprogramms bietet neben einer Genre-Auswahl zusätzlich eine gezielte Suche nach Stichworten.
 
So kann beispielsweise direkt nach Schauspielern, Themen oder Sportarten gesucht werden. Neben dieser Funktion arbeiten die neuen Rekorder mit einer automatischen Kapitelerstellung bei der Aufzeichnung.
Dadurch können während der anschließenden Wiedergabe unerwünschte Programmsequenzen auf Knopfdruck übersprungen oder eine Szene blitzschnell gefunden werden.
Mit Pause Live TV kann zudem das laufende Fernsehprogramm jederzeit mit einem Druck auf die Pause-Taste angehalten und zu einem späteren Zeitpunkt weitergeschaut werden.
Dank Quick Start-Funktion sind die Rekorder innerhalb einer Sekunde einsatzbereit, so dass kein Film und keine Aufzeichnung verpasst werden.
 
  • Multiformat-DVD-Festplatten-Kombination
  • Intuitive Benutzerführung
  • Neben der Aufnahme des Fernsehprogramms überzeugen die neuen Rekorder als digitales Fotoalbum sowie
  • Musik-Jukebox
  • Elektronische Programmführer Guide Plus+ mit Suchfunktion
  • Umfangreiche Anschlussmöglichkeiten
";2;False;0;;;Panasonic DMR EH 495 EG K;panasonic-dmr-eh-495-eg-k-160-gb-dvd-hdd-rekorder;True;True;P-1840;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;319.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40155,8616898148;62;12;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000428-panasonic-dmr-eh-495-eg-k-160-gb-dvd-hdd-rekorder.jpg;;;3;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"HP Compaq Mini 110c-1110sg 10.1 Zoll Netbook ";"HP Compaq Mini 110c-1110sg 10.1 Zoll Netbook ";"
HP Compaq Mini 110c-1110sg 10.1 Zoll Netbook
 
Intel Atom N270 1.6GHz, 1GB RAM, 160GB HDD, Intel GMA 950, Win XP Home
 
Leicht und kompakt
Der Compaq Mini 110c wiegt 1,3 kg (mit 6-Zellen-Akku) und ist ca. 5,5 cm hoch – er ist damit sehr kompakt und fällt ins Auge
 
Elegantes Design
Der Compaq Mini 110c glänzt mit einem eleganten Gehäuse im neuem Imprint-Finish ""Unity"", einem Karomuster, das ins Auge fällt.
 
Ständig in Verbindung
Webcam und Mikrofon sind im Compaq Mini integriert und bieten per WLAN und optionalem WWAN zahlreiche Möglichkeiten zur Pflege sozialer Kontakte; Video-Chats und Video-Konferenzen, die bislang nur zuhause möglich waren, können jetzt im Park, im Cafe oder am Flughafen geführt werden
 
Information und Kommunikation auch unterwegs
Mit dem 10,1-Zoll-BrightView-Display, Original Windows® XP Home, der großen Tastatur (92 % der vollen Größe), drei USB-Anschlüssen und einem 5-in-1 Kartenleser sind Informationen, Kommunikation und Unterhaltung im Internet überall bequem zugänglich.
";2;False;0;;;"HP Compaq Mini 110c-1110sg 10.1 Zoll Netbook ";hp-compaq-mini-110c-1110sg-101-zoll-netbook;True;True;P-0870;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;259.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40151,9990046296;6;39;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000598-hp-compaq-mini-110c-1110sg-101-zoll-netbook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000599-hp-compaq-mini-110c-1110sg-101-zoll-netbook.jpg;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Apple iPod Classic 120 GB schwarz;"Apple iPod Classic 120 GB schwarz ";"

Apple iPod Classic 120 GB schwarz

 
iPod classic: Freiraum -Und zwar jede Menge.
120 GB sind wirklich eine ganze Menge Platz. Da lässt sich eine komplette Mediathek locker unterbringen und überallhin mitnehmen.
 
Ein musikalisches Genie
Stellen Sie vor, Sie hören einen Song. Toll wären jetzt andere Titel, die gut dazu passen. Was machen Sie? Ganz einfach: Sie verwenden die neue Funktion ""Genius"". Diese findet die Songs in Ihrer Mediathek, die gut zusammenpassen. Sie erhalten eine Genius Wiedergabeliste, die Sie sofort anhören, sichern oder sogar aktualisieren können. Verlassen Sie sich also auf den Genius von iTunes, wenn Sie einen Mix wollen, auf den Sie selbst nicht gekommen wären.
 
Platz satt
Der iPod classic bietet mit seinen 120 GB Speicherkapazität Platz für bis zu 30.000 Songs, 180 Stunden Videos, 20.000 Fotos oder eine beliebige Kombination dieser Inhalte. Und mit bis zu 36 Stunden Batterielaufzeit beweist der iPod classic auch ganz schön viel Kondition.
 
Spaß auf Knopfdruck
Sie findeen immer ganz leicht genau das, was Sie sehen oder hören wollen. Mit dem Click Wheel können Sie mit ""Cover Flow"" Ihre Alben durchblättern, oder Sie stöbern über verschiedene Kategorien wie Wiedergabeliste, Künstler, Album oder Musikrichtung in Ihren Songs und Videos. Sie können natürlich auch nach einem bestimmten Titel oder Interpreten suchen. Lust auf einen neuen Mix? Klicken Sie einfach auf ""Zufällige Titel"".
 
Filme und Fernsehsendungen ansehen
Auf dem fantastischen 2,5"" Display kommen Videos richtig zur Geltung. Sie können im iTunes Store Filme kaufen oder ausleihen, Fernsehsendungen kaufen und Video-Podcasts laden. Dann können Sie alles mit Ihrem iPod classic synchronisieren und immer und überall ansehen.
 
 
Spiele auf dem iPod
Wenige Fingertipps, viele Stunden Spielspaß. Vortex, iQuiz und Klondike sind schon auf dem iPod classic vorinstalliert, im iTunes Store können Sie weitere dazukaufen, z. B. Cake Mania. Alle iPod Spiele sind speziell für die iPod Oberfläche optimiert.
 
Fotos zeigen
Ihre Fotos aus iPhoto auf einem Mac oder aus Adobe Photoshop Elements und Adobe Photoshop Album auf einem PC bekommen Sie mit iTunes auf den iPod classic. Sie können Diashows mit Musik und Übergängen auf dem iPod classic oder mit optional erhältlichen Apple Komponenten oder mit einem Composite-AV-Kabel sogar auf dem Fernseher zeigen.
 
Umweltverträglichkeit
Der iPod classic steht für das kontinuierliche Engagement von Apple in puncto Umweltschutz. Die folgenden Merkmale tragen zu einer geringen Umweltbelastung bei:
 
    Arsenfreies Displayglas
    Ohne bromhaltige Flammschutzmittel
    Display mit LED-Hintergrundbeleuchtung ohne Quecksilber
    Frei von PVC
    Recyclingfähiges Gehäuse aus Aluminium und Edelstahl
 
Produktbeschreibungen
Freiraum. Und zwar jede Menge. 160 GB sind wirklich eine ganze Menge Platz. Da lässt sich eine komplette Mediathek locker unterbringen und überallhin mitnehmen.
 
> Highlights
- Click Wheel
- Frequenzbereich: 20 Hz bis 20.000 Hz
- Weitere unterstützte Audioformate: Protected AAC (aus dem iTunes Store), MP3 VBR, Audible (Formate 2, 3, 4, Audible Enhanced Audio, AAX und AAX+), Apple Lossless und WAV
- Platz für bis zu 35.000 Songs im 128 KBit/Sek. AAC-Format
- Platz für bis zu 20.000 vom iPod anzeigbare Fotos
- Platz für bis zu 180 Stunden Videomaterial
- Speichert Daten auf einer USB-Festplatte
- Akkuladezeit: ca. 4 Std. (schnelles Laden auf 80%ige Kapazität in 2 Std.)
 
> Grundeigenschaften
- Breite: 103.5 mm
- Höhe: 61.8 mm
- Tiefe: 10.5 mm
- Gewicht: 140.0 g
- Farbe: Schwarz
 
> Wiedergabeformate Audio
- AAC
- MP3
- WAV
 
> Akku
- Akkutyp: Li-Ion
 
> Display
- Displaytechnologie: LCD
- 2.5- Display
- Bilddiagonale: 6.35 cm
- Auflösung Breite: 320 Pixel
- Auflösung Höhe: 240 Pixel
- Hintergrundbeleuchtung: ja
 
> Speicher
- Speicherkapazität 120 GB
 
> Anschlüsse
- USB
- USB-Standard 2.0
 
> Audio-Anschlüsse
- Headsetanschluss: 3,5 mm Klinke
- ipod-Anschluss via IPOD Connector
 
> Lieferumfang
- iPod classic
- Apple Earphones
- USB 2.0 Kabel
- Dock-Adapter
- Dokumentation
 
> Umweltverträglichkeit
Der iPod nano steht exemplarisch für das Engagement von Apple in puncto Umweltschutz. Die folgenden Merkmale des iPod nano tragen zu seiner geringeren Umweltbelastung bei:
- Arsenfreies Glas
- Frei von bromhaltigen Flammschutzmitteln
- Frei von Quecksilber
- Frei von PVC
- Besonders recyclingfähig
";2;False;0;;;Apple iPod Classic 120 GB schwarz;apple-ipod-classic-120-gb-schwarz;True;True;P-1420;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;209.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40151,9525462963;50;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000284-apple-ipod-classic-160-gb-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000285-apple-ipod-classic-160-gb-schwarz.jpg;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Garmin nüvi 1370T Navigationssystem ";"Garmin nüvi 1370T Navigationssystem Europa USA ";"
Garmin nüvi 1370T Navigationssystem
 
 

TMC, 4,3"" Display, Europa / USA / Kanada, ecoRoute, Fußgängernavigation, Bluetooth

 
 
 
Mobile Navigation für die ganze Familie, dank Fahrspurassistent, intelligentem TMC, und Text-to-Speech eine rund-um-sorglos Navigation
Übersichtliche und einfache Navigation mit 4,3 Zoll Display mit Fahrspurassistent + TMC Verkehrsfunkempfänger zur Stauumfahrung
Kartenmaterial für Europa, USA und Canada intern vorinstalliert
Inklusive ecoRoute die Garmin Spritspar-Funktion und echter Fußgängernavigation mit optionalen CityXplorer Stadtplänen für Bus und Bahn
Lieferumfang: Garmin nüvi 1370T mit Kartenmaterial Europa/ USA/ Canada, KFZ-Anschlusskabel mit TMC Verkehrsfunkempfänger,
Saugnapfhalterung für die Windschutzscheibe, Armaturenhalterung, Kurzanleitung
";2;False;0;;;"Garmin nüvi 1370T Navigationssystem ";garmin-nuevi-1370t-navigationssystem;True;True;P-2100;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;359.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40148,9306828704;67;44;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000589-garmin-nuvi-1370t-navigationssystem.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;NAVIGON 8410 Navigationssystem Europa;" NAVIGON 8410 Navigationssystem Europa 5"" Echtglas-Display";"
NAVIGON 8410 Navigationssystem Europa
 
 
5"" Echtglas-Display, West & Osteuropa 40 Länder, Bluetooth, TMC Pro, Real City 3D, Voice Interaction Pro
 
 
5-Zoll-Touchdisplay 16:9
Fußgängernavigation
Reality View Pro
Fahrspurassistent Pro
Radar-Info
Geschwindigkeitsassistent
Reale Beschilderung Pro
Clever Parking
Text-to-Speech für Straßennamen
Bluetooth Freisprecheinrichtung
Professionelle Sprachsteuerung 2.0
Landmark View 3D/City View 3D
Panorama View 3D
Latest Map Guarantee
Europakarte (40 Länder)
Abmessungen: 138 mm x 83,5 mm x 18,7mm (B/H/T)
Lieferumfang: NAVIGON 8410, Kurzanleitung, KfZ-Ladekabel mit integrierter TMC Antenne,
Design-Aktivhalterung, USB-Kabel, vorinstalliertes Europa-Kartenmaterial
";2;False;0;;;"NAVIGON 8410 Navigationssystem ";navigon-8410-navigationssystem-europa;True;True;P-2170;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;449.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40148,9205902778;"68;2095";14;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000470-navigon-8410-navigationssystem-europa.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Apple iPod shuffle 2 GB blau;Apple iPod shuffle 2 GB blue;"

Apple iPod shuffle 2GB blau 

 
 
Wie seine größeren Geschwister besitzt auch der iPod shuffle kreisförmig
angeordnete, ergonomische Bedienelemente.
Der Kopfhöreranschluss am iPod shuffle dient gleichzeitig als Dock-Anschluss.
Drehen Sie den iPod shuffle auf die Seite und setzen Sie ihn in das mitgelieferte Dock ein.
Dank eines stabilen, integrierten Clips lässt sich der iPod shuffle fast überall befestigen.
Klemmen Sie ihn am T-Shirt, am Hemdkragen oder am Trageriemen von Rucksack oder Handtasche fest.
Lassen Sie sich aufs Ungewisse ein: Verwenden Sie den Schalter für die Zufallswiedergabe,
um den Inhalt Ihres iPod shuffle neu zu mischen.
verbesserte Kopfhörer und das neue iTunes 8.0
 
Einfach Musik anhaben mit dem Apple iPOD SHUFFLE 2GB.Tragen Sie bis zu 500 Songs am Ärmel. Oder am Gürtel. Oder am Sportoutfit. Das Erkennungszeichen für Musikfans - den Apple iPOD SHUFFLE. Füllen Sie Ihren Apple iPOD SHUFFLE silber 1GB spielend einfach. iTunes ist der Store für Unterhaltungsinhalte. Ihre super organisierte Musiksammlung und Jukebox. Und die Software, mit der Sie Ihren Apple iPOD SHUFFLE mit einem Mausklick füllen. Das farbige Gehäuse aus eloxiertem Aluminium in silber passt zum genial einfachen Design des Apple iPOD SHUFFLE.
 
Leistungseigenschaften
 
2 GB Flash-Memory Speicher
min. Audio-Datenrate: 8 KBit/s
max. Audio-Datenrate: 320 KBit/s
Frequenzgang-Untergrenze: 20 Hz
Frequenzgang-Obergrenze: 20000 Hz
 
Formate/Standards
 
MP3-Standard
AAC + MP3 Standard
WAV-Dateiformat kompatibel
Audible-Format kompatibel
AIFF-Format kompatibel
 
Bedienung
 
Musiktitel-Verwaltung
 
Leistungsaufnahme/Spannungsversorgung

Li-Polymer Akku
12 Std. Spieldauer mit Akku
Ladezeit für Akku: 4 Std.
 
Anschlüsse
 
Kopfhörer-Anschluß
USB-Schnittstelle
Anschluß für Docking-Station
 
Gehäuse-Eigenschaften
 
Breite: 4.12 cm
Höhe: 2.73 cm
Tiefe: 1.05 cm
Gewicht: 15.5 g
";2;False;0;Apple iPod shuffle 2 GB blau;Apple iPod shuffle 2 GB blau;Apple iPod shuffle 2 GB blau;apple-ipod-shuffle-2-gb-blau;True;True;P-1150;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;64.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40148,0555902778;37;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000398-apple-ipod-shuffle-2-gb-blau.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000399-apple-ipod-shuffle-2-gb-blau.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000400-apple-ipod-shuffle-2-gb-blau.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Logitech EX 110 Desktop Tastatur/Maus ";Logitech EX 110 Desktop Tastatu / Maus;"
Logitech EX 110 Desktop Tastatur/Maus
 
 
Zuverlässig und kabellos:
Schnelle, kabellose 27-MHz-Leistung
Sondertasten: Zugriff auf Musik, Video, Lautstärke, E-Mail, Internet und mehr.
Programmierbare F-Tasten: öffnen häufig genutzter Anwendungen, Websites oder Dateien.
Spritzwassergeschütztes Design
Maus: Schnell ansprechende Optik: Erleben Sie eine Auflösung von 800 dpi.
 
Lieferumfang:
Logitech Cordless Keyboard und Cordless Optical Mouse,
kompakter USB-/PS/2-Funkempfänge, USB-PS/2-Adapter
 
";2;False;0;;;"Logitech EX 110 Desktop Tastatur/Maus ";logitech-ex-110-desktop-tastaturmaus;True;True;P-2810;;;False;0;False;;False;False;0;False;0;1;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;24.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40143,0133101852;"21;2095";11;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000392-logitech-ex-110-desktop-tastaturmaus.jpg;;;1;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"TomTom GO 940 Live Navigationssystem ";"TomTom Go 940 Live Navigationssystem Europa Nordamerika ";"
TomTom GO 940 Live Navigationsgerät mit Sprachsteuerung

 
inkl. Europa-Karten, USA, Kanada, TMC, Live Services

 
Clevere Navigation mit Echtzeitinfos für Vielfahrer und dem neuesten Kartenmaterial von West- und Osteuropa, USA und Kanada, TomTom IQ Routes -
jeden Tag zu jeder Tageszeit die optimalste Route, TomTom Map Share, vereinfachte Bedienung durch brillianten 4,3-Zoll-Touchscreen und Sprachsteuerung,
verbesserter Fahrspurassistent zur einfacheren Orientierung an unübersichtlichen Autobahnkreuzen, hochwertiger Bluetooth-Kfz-Freisprecheinrichtung sowie einem FM-Transmitter und MP3-Player.
TomTom GO 940 Live inklusive 3 Monate Probe-Abo zu Live-Dienste in allen LIVE Ländern. Echtzeit-Empfang von Premiuminformationen zu Ihrer Route: HD Traffic, Lokale Suche mit Google, Sicherheitswarnungen und mehr
 Sprachsteuerung - mehr als 100 Funktionen einfach per Sprachbefehl aktivieren
Verbesserte Positionsbestimmung - unterbrechungsfreie Navigation, sogar in Tunneln
Fahrspurassistent - zum einfachen Navigieren an unübersichtlichen Kreuzungspunkten
GO 940 LIVE: Karten von Europa (WE u. OE), den USA und Kanada vorinstalliert, LIVE-Services- fahren Sie immer aktuell und zuverlässig informiert mit Echtzeit-Informationen
sowie mit IQ Routes damit fahren Sie zu jeder Tageszeit auf der cleversten Route
Lieferumfang: TomTom GO 940 LIVE, aktive Halterung, Autoladegerät, Halterung für Zuhause, Benutzerhandbuch, CD-ROM (TomTom HOME )

 
";2;False;0;;;;tomtom-go-940-live-navigationssystem;True;True;P-2010;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;304.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40136,6372800926;66;4;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000391-tomtom-go-940-live-navigationssystem.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Apple iPod Touch 8 GB schwarz;"Apple iPod Touch 8 GB schwarz mit integrierter WiFi Funktion ";"
Apple iPod Touch 32 GB schwarz mit integrierter WiFi Funktion

Der iPod touch kann alles, was du am iPod toll findest. Und noch vielmehr. Schlankes neues Design. Mit seinem fantastisch flachen Edelstahl-Design liegt der iPod touch mit dem 3.5 Zoll Touch-Display jetzt noch besser in der Hand. Mobil im Spiel. Durch revolutionäre Technologien wie das Multi-Touch-Display, der Beschleunigungssensor und 3D-Grafiken macht das Spielen auf dem iPod touch besonders viel Spaß. Schlaue Musik Mit der neuen Funktion ""Genius"" wird der iPod touch zu Deinem superintelligenten, persönlichen DJ.
Nur ein paar Fingertipps, und Genius erzeugt eine Wiedergabeliste mit Songs Deiner Mediathek, die gut zusammenpassen. Internet überall Internetzugang überall, wo ein drahtloses Netzwerk zur Verfügung steht, damit Sie immer mit dabei sind. Multitouch-Oberfläche: Die revolutionäre Technologie des iPhone und die Software Version 3.1 stecken in diesem genialen iPod. Das brillante Breitformat-Display rückt Ihre Videos und Spiele ins beste Licht und dank OpenGL sehen die Spiele jetzt noch besser aus Surfen Sie mit Safari im Web und sehen Sie YouTube Videos auf dem iPod mit integrierter Wi-Fi Funktionalität an. Mit Ihrem iPod touch können Sie im iTunes Wi-Fi Music Store nach Songs suchen, Hörproben abspielen und Titel kaufen.
Lieferumfang: iPod touch, Ohrhörer, USB 2.0 Kabel, Kurzanleitung
 
Schlankes neues Design
Mit seinem fantastisch flachen Edelstahl-Design liegt der iPod touch so gut in der Hand wie nie zuvor. Ebenfalls Eindruck machen der neue Lautstärkeregler und der integrierte Lautsprecher.

Spiele
Speziell auf die iPod touch Technologie zugeschnittene Spiele sind nur noch einen Fingertipp entfernt. Stöbere in hunderten von Spielen im App Store direkt auf Deinem iPod touch, und wenn Du gefunden hast, was Du suchst, kannst Du es einfach laden und dann kann es losgehen.
 
Steuerung per Fingertipp
Viele Spiele auf dem iPod touch nutzen die Multi-Touch-Technologie für besonders exakte Fingertipp-Steuerung der verschiedenen Spielelemente. Beim Schach ziehst Du mit dem Finger die Figuren, bei Würfelspielen bewegst Du die Würfel. Durch Ziehen mit zwei Fingern kannst Du die Anzeige vergrößern und verkleinern, Deine Figur nach links oder rechts drehen, und durch einfaches Antippen triffst Du eine Auswahl.
 
Musik
Blättere in den Albumcovern Deiner Musiksammlung. Erstelle immer wieder neue Genius Wiedergabelisten und erweitere Deine Sammlung aus dem iTunes Wi-Fi Music Store überall, wo ein Wi-Fi-Hotspot in der Nähe ist.
Mit Cover Flow lebt das Flair einer CD- oder Plattensammlung wieder auf. Wer erinnerst sich nicht an das Gefühl beim Durchblättern der Sammlung? Das gibt es jetzt auch auf dem iPod touch: einfach iPod drehen, durch die Cover blättern, ein Album auswählen, fertig. Ein Fingertipp aufs Cover, und schon siehst Du die Titelliste, ein weiterer Tipp spielt die Musik ab, und dabei kannst Du sogar die Songtexte anzeigen.
 
Ein Musikgenie
Stell Dir vor, Du hörst einen Song. Toll wären jetzt andere Titel, die gut dazu passen. Was machst du? Ganz einfach: Du verwendest die neue Funktion ""Genius"". Diese findet die Songs in Deiner Mediathek, die gut zusammenpassen. Du erhältst eine Genius Wiedergabeliste, die Du sofort anhören, sichern oder sogar aktualisieren kannst. Verlass Dich also auf den Genius von iTunes, wenn Du einen Mix willst, auf den Du selbst nicht gekommen wärst.
 
Lautsprecher integriert
Mit dem integrierten Lautsprecher kannst Du Musik und Gespräche ohne Kopfhörer hören – perfekt für zwangloses Hörvergnügen.

Längere Batterielaufzeit
Jetzt kannst Du noch länger rocken (und ansehen und spielen). Der iPod touch hält bis zu 36 Stunden bei Musik oder bis zu 6 Stunden bei Videos durch. Das reicht für drei oder vier Filme zwischen den Ladevorgängen.
 
Internet
Surfe im Internet mit Wi-Fi. Du kannst detailgenaue HTML-E-Mails mit Anlagen empfangen und Wegbeschreibungen und aktuelle Verkehrsinformationen abrufen. Auch als YouTube-Fan entgeht Dir nichts.
 
Überall ins Internet
Der iPod touch ist der einzige iPod mit kabellosem 802.11b/g Internetzugriff. Bei bestehender Wi-Fi-Verbindung kannst Du im Internet surfen und Nachrichten lesen, Sportergebnisse sehen, Rechnungen bezahlen und online einkaufen.
 
Wer suchet, der findet
Der iPod touch synchronisiert Deine Lesezeichen vom PC oder Mac, sodass Du ruck zuck auf Deine Lieblingsseiten zugreifen kannst. Die Google- und Yahoo!-Suche ist schon integriert, sodass Du im Web schnell findest, was Du suchst.
 
Zoom mit Aussicht
Jeden beliebigen Ausschnitt einer Webseite kannst Du vergrößern, indem Du mit dem Finger darauf tippst oder mit zwei Fingern die Anzeige aufziehst. Websites lassen sich im Hoch- oder Querformat anzeigen: einfach den iPod touch um 90 Grad drehen, und schon wird auch die Darstellung der Website gedreht.
 
Eigene Weblinks
Für häufig besuchte Websites, etwa die einer Zeitung, eines Blogs oder eine Sport-Website, kannst Du einfach ein Symbol auf dem Home-Bildschirm erstellen. Deine Lieblingsseiten sind über mit Safari erstellte Weblinks nur einen Fingertipp entfernt.
 
Rock 'n' Run mit Nike+
Im iPod touch ist kabellose Unterstützung für Nike + iPod integriert. Du brauchst nur einen Nike + iPod Sensor in Deinem Schuh, und schon kann's losgehen.
 
Das optimale Lauftraining
Im iPod touch ist jetzt Unterstützung für Nike + iPod integriert. Einfach den Nike + iPod Sensor (separat erhältlich) in den Nike+ Laufschuh einsetzen, und es kann losgehen. Der Sensor überträgt die Laufdaten drahtlos an den iPod touch – er erfasst die gelaufene Zeit, die zurückgelegte Strecke und die verbrauchten Kalorien. Außerdem gibt er Dir gesprochenes Feedback zu Deinen Trainingsfortschritten.
 
Das optimale Fitnesstraining
Diese Funktion kann auch zusammen mit neuen, in vielen Fitnessstudios vorhandenen Geräten für das Ausdauertraining gekoppelt werden. Suche einfach nach mit Nike + iPod kompatiblen Laufbändern, Elliptical Trainern, Steppern und Hometrainern.
";2;False;0;;;Apple iPod Touch 8 GB schwarz mit integrierter WiFi Funktion;apple-ipod-touch-8-gb-schwarz;True;True;P-1270;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;169.9000;169.9000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40134,2799768519;43;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000141-apple-ipod-touch-16-gb-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000142-apple-ipod-touch-16-gb-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000143-apple-ipod-touch-16-gb-schwarz.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Philips DVP 5990 / 12 DVD Player ";Philips DVP 5990 / 12 DVD Player schwarz;"
Philips DVP 5990 / 12 DVD Player schwarz
 
DivX-zertifiziert, HDMI 1080p, Upscaling 1080i
 
Der ideale DVD-Player für Ihr HDTV
mit True High-Definition-HDMI 1080p
Lassen Sie sich von diesem DVD-Player von Philips mit HDMI Digital Video- und
Audioverbindung beeindrucken. Erleben Sie wahres Home Entertainment, und tauchen
Sie in High Definition Video ein (720p / 1080i / 1080p).
Digitaler HDMI-Ausgang für eine einfache Verbindung mit nur einem Kabel
DivX Ultra-zertifiziert für verbesserte Wiedergabe von DivX-Videos
192 kHz/24 Bit Audio-DAC für verbesserte analoge Klangausgabe
Hochwertige Ausgänge für Analog- und Digital-Audio
 
Lieferumfang:
DVD Player; 2 AAA-Batterien; Schnellstartanleitung; Fernbedienung; Benutzerhandbuch
";2;False;0;;;"Philips DVP 5990 / 12 DVD Player ";philips-dvp-5990-12-dvd-player;True;True;P-1930;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;89.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40132,644837963;60;6;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000383-philips-dvp-5990-12-dvd-player.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000384-philips-dvp-5990-12-dvd-player.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000385-philips-dvp-5990-12-dvd-player.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Sandisk Sansa Clip+ schwarz 8GB;Sandisk Sansa Clip+ schwarz 8 GB;"
Sandisk Sansa Clip+ schwarz 8 GB
 
 
 
Die neuen Sandisk Sansa Clip+ - Modelle unterstützen nun die Anzeige von sortierbaren Ordnerstrukturen.
digitaler SanDisk Player für MP3, WMA, Secure WMA, Ogg Vorbis, FLAC-Formate, Hörbücher und FM-Radio
kleines, kompaktes Design, kaum größer als eine Streichholzschachtel
microSD-/microSDHC-Slot zur Erweiterung der Speicherkapazität und zum Datentransfer
FM-Radio mit 40 Stationsspeicherplätzen
Diktiergerät-Funktion über integriertes Mikrofon
4-zeiliges OLED-Display
Sortierung der Titel nach verschiedenen Kriterien möglich, wie z.B. Künstler, Album, Genre, u.a.
bis zu 15-h-Wiedergabe mittels internem, wiederaufladbaren Akku
inkl. abnehmbarem Trageclip, Ohrhörer, USB 2.0 Kabel und Bedienungsanleitung
unterstützt Win 2000, Vista, XP SP2 und Mac OS X 10.3 oder höher
Speicherkapazität extern: wird über microSD-Karte definiert
Speicherkapazität intern: 8 GB
Speicher: intern + extern

Lieferumfang:
Sansa Clip+ MP3 Player, Ohrhörer, USB 2.0 Kabel, Quick Start Guide
";2;False;0;;;Sandisk Sansa Clip+;sandisk-sansa-clip-schwarz-8gb;True;True;P-1590;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;59.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40125,6367476852;52;8;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000572-sandisk-sansa-clip-schwarz-8gb.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Me2 ME600HD-1000 Multimediafestplatte ";"Me2 ME600HD-1000 Multimediafestplatte1 TB ";"

Me2 ME600HD-1000  Multimediafestplatte 1 TB

 
 
3,5 Zoll, USB 2.0,Scart,HDMI Multimedia
 
 
 
Externe USB 2.0 Multimedia Festplatte• Kapazität: 1000 GB• High-speed
USB 2.0 Schnittstelle• Aluminium Gehäuse• Stand-alone Media Player zur Wiedergabe von MPEG-1, MPEG-2,
D ivX/Xvid, JPEG, GMC, Qpel, MP3 (ID3 tag) WAV Media Daten• direkte Wiedergabe von DVD Ordnern&bu
Ordner-Navigation• Eigene Playlist benutzen und bearbeiten• einfache Dateiführung,
 intuitive Bedienung• unterstützt NTSC und PAL TV Standard• geeignet für HDTV (skaliert auf 10
";2;False;0;;;;me2-me600hd-1000-multimediafestplatte;True;True;P-2670;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;169.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40124,2896180556;16;;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000117-me2-me600hd-500-gb-multimediafestplatte.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Apple iPod Classic 160 GB silber;"Apple iPod Classic 160 GB silber ";"
Apple iPod Classic 160 GB silber


iPod classic: Freiraum -Und zwar jede Menge.
160 GB sind wirklich eine ganze Menge Platz. Da lässt sich eine komplette Mediathek locker unterbringen und überallhin mitnehmen.
 
Ein musikalisches Genie
Stellen Sie vor, Sie hören einen Song. Toll wären jetzt andere Titel, die gut dazu passen. Was machen Sie? Ganz einfach: Sie verwenden die neue Funktion ""Genius"". Diese findet die Songs in Ihrer Mediathek, die gut zusammenpassen. Sie erhalten eine Genius Wiedergabeliste, die Sie sofort anhören, sichern oder sogar aktualisieren können. Verlassen Sie sich also auf den Genius von iTunes, wenn Sie einen Mix wollen, auf den Sie selbst nicht gekommen wären.
 
Platz satt
Der iPod classic bietet mit seinen 160 GB Speicherkapazität Platz für bis zu 40.000 Songs, 200 Stunden Videos, 25.000 Fotos oder eine beliebige Kombination dieser Inhalte. Und mit bis zu 36 Stunden Batterielaufzeit beweist der iPod classic auch ganz schön viel Kondition.
 
Spaß auf Knopfdruck
Sie findeen immer ganz leicht genau das, was Sie sehen oder hören wollen. Mit dem Click Wheel können Sie mit ""Cover Flow"" Ihre Alben durchblättern, oder Sie stöbern über verschiedene Kategorien wie Wiedergabeliste, Künstler, Album oder Musikrichtung in Ihren Songs und Videos. Sie können natürlich auch nach einem bestimmten Titel oder Interpreten suchen. Lust auf einen neuen Mix? Klicken Sie einfach auf ""Zufällige Titel"".
 
Filme und Fernsehsendungen ansehen
Auf dem fantastischen 2,5"" Display kommen Videos richtig zur Geltung. Sie können im iTunes Store Filme kaufen oder ausleihen, Fernsehsendungen kaufen und Video-Podcasts laden. Dann können Sie alles mit Ihrem iPod classic synchronisieren und immer und überall ansehen.
 
 
Spiele auf dem iPod
Wenige Fingertipps, viele Stunden Spielspaß. Vortex, iQuiz und Klondike sind schon auf dem iPod classic vorinstalliert, im iTunes Store können Sie weitere dazukaufen, z. B. Cake Mania. Alle iPod Spiele sind speziell für die iPod Oberfläche optimiert.
 
Fotos zeigen
Ihre Fotos aus iPhoto auf einem Mac oder aus Adobe Photoshop Elements und Adobe Photoshop Album auf einem PC bekommen Sie mit iTunes auf den iPod classic. Sie können Diashows mit Musik und Übergängen auf dem iPod classic oder mit optional erhältlichen Apple Komponenten oder mit einem Composite-AV-Kabel sogar auf dem Fernseher zeigen.
 
Umweltverträglichkeit
Der iPod classic steht für das kontinuierliche Engagement von Apple in puncto Umweltschutz. Die folgenden Merkmale tragen zu einer geringen Umweltbelastung bei:
 
    Arsenfreies Displayglas
    Ohne bromhaltige Flammschutzmittel
    Display mit LED-Hintergrundbeleuchtung ohne Quecksilber
    Frei von PVC
    Recyclingfähiges Gehäuse aus Aluminium und Edelstahl
 
Produktbeschreibungen
Freiraum. Und zwar jede Menge. 160 GB sind wirklich eine ganze Menge Platz. Da lässt sich eine komplette Mediathek locker unterbringen und überallhin mitnehmen.
 
> Highlights
- Click Wheel
- Frequenzbereich: 20 Hz bis 20.000 Hz
- Weitere unterstützte Audioformate: Protected AAC (aus dem iTunes Store), MP3 VBR, Audible (Formate 2, 3, 4, Audible Enhanced Audio, AAX und AAX+), Apple Lossless und WAV
- Platz für bis zu 40.000 Songs im 128 KBit/Sek. AAC-Format
- Platz für bis zu 25.000 vom iPod anzeigbare Fotos
- Platz für bis zu 200 Stunden Videomaterial
- Speichert Daten auf einer USB-Festplatte
- Akkuladezeit: ca. 4 Std. (schnelles Laden auf 80%ige Kapazität in 2 Std.)
 
> Grundeigenschaften
- Breite: 103.5 mm
- Höhe: 61.8 mm
- Tiefe: 10.5 mm
- Gewicht: 140.0 g
- Farbe: Schwarz
 
> Wiedergabeformate Audio
- AAC
- MP3
- WAV
 
> Akku
- Akkutyp: Li-Ion
 
> Display
- Displaytechnologie: LCD
- 2.5- Display
- Bilddiagonale: 6.35 cm
- Auflösung Breite: 320 Pixel
- Auflösung Höhe: 240 Pixel
- Hintergrundbeleuchtung: ja
 
> Speicher
- Speicherkapazität 160 GB
 
> Anschlüsse
- USB
- USB-Standard 2.0
 
> Audio-Anschlüsse
- Headsetanschluss: 3,5 mm Klinke
- ipod-Anschluss via IPOD Connector
 
> Lieferumfang
- iPod classic
- Apple Earphones
- USB 2.0 Kabel
- Dock-Adapter
- Dokumentation
 
> Umweltverträglichkeit
Der iPod nano steht exemplarisch für das Engagement von Apple in puncto Umweltschutz. Die folgenden Merkmale des iPod nano tragen zu seiner geringeren Umweltbelastung bei:
- Arsenfreies Glas
- Frei von bromhaltigen Flammschutzmitteln
- Frei von Quecksilber
- Frei von PVC
- Besonders recyclingfähig
";2;False;0;;;Apple iPod Classic 120 GB schwarz;apple-ipod-classic-160-gb-silber;True;True;P-1410;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;249.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40124,2541319444;50;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000285-apple-ipod-classic-160-gb-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000284-apple-ipod-classic-160-gb-schwarz.jpg;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Apple iPod Nano 16 GB verschiedene Farben;Apple iPod Nano 16 GB;"
Apple iPod Nano 16 GB
 
 
Neues gebogenes Design, der dünnste iPod, den es je gab mit neuen Farben zu Auswahl
Die Bedieung optimiert: ein einziges Handschütteln und ein anderes Lied wird gespielt
Die neue Funktion ""Genius"" findet die Songs in Ihrer Mediathek, die besonders gut zusammenpassen, und erstellt daraus eine Genius Wiedergabeliste.
Viele Abspielformate: z.B. MP3, AAC, Apple Lossless, AIFF, WAV, H.264, MPEG-4
Lieferumfang: iPod Nano, Ohrhörer, USB 2.0 Kabel, Dock-Adapter, Dokumentation
 
Neues gebogenes Design, der dünnste iPod, den es je gab mit neuen Farben zu Auswahl
Die Bedieung optimiert: ein einziges Handschütteln und ein anderes Lied wird gespielt
Die neue Funktion ""Genius"" findet die Songs in Ihrer Mediathek, die besonders gut zusammenpassen, und erstellt daraus eine Genius Wiedergabeliste.
Viele Abspielformate: z.B. MP3, AAC, Apple Lossless, AIFF, WAV, H.264, MPEG-4
Lieferumfang: iPod Nano, Ohrhörer, USB 2.0 Kabel, Dock-Adapter, Dokumentation
 
Ein musikalisches Genie
Stell Dir vor, Du hörst einen Song. Toll wären jetzt andere Titel, die gut dazu passen. Was machst du? Ganz einfach: Du verwendest die neue Funktion ""Genius"". Diese findet die Songs in Deiner Mediathek, die gut zusammenpassen. Du erhältst eine Genius Wiedergabeliste, zusammengestellt von Deinem persönlichen, superintelligenten DJ.  
Musik schneller finden
Auch einen Song, den Du hören willst, findest Du jetzt viel einfacher. Du kannst Deine Alben mit Cover Flow anzeigen oder hältst einfach die mittlere Taste gedrückt und blätterst in Deinen Alben oder Interpreten. Den gewünschten Song gefunden? Einmal auf die mittlere Taste gedrückt, und schon hast Du ihn zur aktuellen Wiedergabeliste hinzugefügt. 
 
Aufdrehen und rumdrehen
Neige Deinen iPod nano in die Waagerechte, und schon kannst Du hören, sehen oder spielen wie nie zuvor. Deine Alben kannst Du mit Cover Flow durchblättern und siehst so viel mehr Alben oder Interpreten gleichzeitig auf dem Display.
 
Shake it, Baby!
Manchmal hat man einfach Lust auf eine kleine Überraschung. Darum kannst Du jetzt komplett dem Zufall überlassen, welches Lied Du als Nächstes hörst. Einfach den iPod nano kurz schütteln – und er springt zu irgendeinem anderen Song aus Deiner Musik-Bibliothek. Lass dich überraschen, was er Dir als Nächstes präsentiert.   
Spiel ab!
Jetzt kannst Du Dir mit Spielen die Zeit vertreiben, die ganz speziell auf den iPod nano und den Beschleunigungssensor zugeschnitten sind. Sie reagieren auf Deine Bewegungen und wirken dadurch so überzeugend, dass sie fast schon süchtig machen können. In jedem Fall wirst Du begeistert sein. Bereits vorinstalliert ist Maze, wo Du Dich durch Neigen, Kippen und allerlei andere Bewegungen durch riesige Labyrinthe manövrieren musst. Im iTunes Store stehen natürlich noch viele weitere Spiele zur Auswahl.
 
Sogar Deine Fotos rocken
Jetzt kannst Du gleich hunderte von Fotos aus der Tasche zaubern und überall vorführen. Senkrecht gehalten zeigt der iPod nano Deine Fotos im Hochformat an, wenn Du ihn um 90 Grad drehst, wechseln auch die Fotos ins Querformat. Die Fotos wirken in ihrem richtigen Größen- und Seitenverhältnis auf dem brillanten Display mit 320 x 240 Pixeln einfach hervorragend. 
Der größte kleine Bildschirm der Welt
Filme, Fernsehsendungen und Videos auf dem iPod nano anzusehen, ist das pure Vergnügen. Die hochauflösende Anzeige wirkt auf dem kristallklaren 2"" Breitbild-Display besonders brillant und lebendig. So hast Du mit dem iPod nano Dein eigenes Kino im Taschenformat immer dabei.  
 
Produktbeschreibungen
Flach, flacher, am flachsten mit nur 6,2mm bringt der iPod nano, in leuchtenden Farben, neuen Schwung ins Leben.
Mit brilianterem Display, höherer Speicherkapazität und noch längerer Batterielaufzeit schütteln Sie sich einfach durch Ihre Mediathek.
Leistungsmerkmale
- Verschieden Menüs: Musik, Fernsehsendungen, Videos, Hörbücher, Podcasts, Diashows, Spiele
- Geschwungenen Aluminium-Design mit gewölbtem Glas
- HxBxT: 90,7 x 38,7 x 6,2 mm
- Gewicht: 36,8 g
Lieferumfang
- iPod nano
- Ohrhörer
- USB 2.0-Kabel
- Dock-Adapter
- Dokumentation
Display
- 2- Farb-LCD mit LED-Hintergrundbeleuchtung
- 320 x 240 Pixel
Kapazität
- 8 GB Flash-Laufwerk1 für bis zu 2.000 Songs, 7.000 Fotos, 8 Std. Videomaterial
Batterie
- Integrierte, wiederaufladbare Lithium-Ionen-Batterie
- Musikwiedergabe: bis zu 24 Stunden bei voller Ladung
- Videowiedergabe: bis zu 4 Stunden bei voller Ladung
Audio
- Unterbrechungsfreie Wiedergabe
- Frequenzbereich: 20 Hz bis 20.000 Hz
- Unterstützte Audioformate: AAC, Protected AAC, MP3, MP3 VBR, Audible, Apple Lossless, AIFF und WAV
Systemvoraussetzungen
- USB 2.0-Anschluss
- mind. Mac OS X 10.4.11 bzw. mind. Windows Vista oder Windows XP Home oder Professional
- mind. iTunes 8  

 
 
 
";2;False;0;;;Apple iPod Nano 16 GB;apple-ipod-nano-16-gb-verschiedene-farben;True;True;P-1370;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;159.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40123,68375;47;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000075-apple-ipod-nano-8-gb-verschiedene-farben.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000076-apple-ipod-nano-8-gb-verschiedene-farben.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000077-apple-ipod-nano-8-gb-verschiedene-farben.jpg;1;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Acer Aspire 1810TZ-412G32n rot 29,5 cm (11,6 Zoll) Notebook;4 GB, 17 Zoll, 400 GB, Intel, 3;"
Aspire 1810T:
Das Aspire 1810T bietet die perfekte Balance aus unabhängiger Mobilität und flexibler Anwendung. Dieses handliche 29,46cm (11,6"") Notebook ist weniger als 1"" schmal, wartet aber auf mit einer vollausgestatteten Tastatur, HD Audio/Visual Unterhaltung und bis zu 8 Stunden mobiler Energie. Zusätzlich können Sie unter drei angesagten Farben auswählen: rubinrot, diamantschwarz und saphirblau.
 
 Kompaktes Design, excellente Anwendung
Dieses Notebook wiegt nur 1,35kg, so daß Sie es mühelos überall mitführen können. Mit der Acer Fine Tip Tastatur können Sie auch auf die übliche Notebook Nutzung zugreifen, dank der fortschrittlichen Kontrolle ohne Maus über das multifunktionale Touchpad.
 
8 Stunden Batterielaufzeit
Das Aspire 1810T ist mit einem Niedrig_Volt-Prozessor (ULV) versehen, der weniger Energie verbraucht und Sie von Ihrem Stromanschluß unabhängig macht. Einmal aufladen und Sie haben es von morgens bis abends zur Verfügung.
 
HD Erfahrung auf dem Vormarsch
Erleben Sie grandiose visuelle Effekte, brillant in Farbe und Bild, via 3D Grafik und einem 16:9 Bildschirm. Der integrierte HDMI Port ermöglicht Ihnen auch den leichten Anschluß an periphere Displays. Was den Klang angeht, erhalten Sie die optimierte 2. Generation des Dolby Sound Room für eine Tonerfahrung über viele Kanäle, zu empfangen über ein simples Paar Kopfhörer.
 
Auf den Punkt gekühlt
Die Acer ComfyTouch Technologie nutzt das innovative Design, um den Prozessor und das Gehäuse luftzukühlen. Auch wenn Sie das Notebook rund um die Uhr in Betrieb haben, bleibt es stets bei optimaler Temperatur.
 

Umweltbewußtsein als Motiv
Nehmen Sie die Energieersparnis wahr, ob unterwegs oder zuhause. In der Anwendung braucht das Aspire 1810T bis zu 40% weniger Strom als handelsübliche Notebooks.
 
 Nutzen Sie die Vorteile der mobilen Welt und schreiben Sie E-Mails oder chatten Sie mit Ihren Lieben, wo auch immer Sie gerade sind. Mit der erweiterten Netzwerkverbindung Wi-Fi CERTIFIED™ können Sie sich problemlos auf eine große Zahl von Verbindungen überall auf der Welt verlassen. Sie müssen sich an ein LAN anschließen? Kein Problem! Der Gigabit-Ethernet-Port garantiert eine ultraschnelle Verbindung.
 
 Die Acer Crystal Eye Webcam mit verbesserter Bilderfassung garantiert auch bei nicht optimaler Beleuchtung ein klares Bild bei Video-Chats und Webkonferenzen.
 
 HD-Ready (engl. „Bereit für HD“) ist ein von der der EICTA geschaffenes Label für Geräte (z.B.: Notebooks) die hochauflösendes Fernsehen (High Definition Television (HDTV)) wiedergeben können. Mindestvorsausetzungen für dieses Label sind unter anderem eine native 16:9-Auflösung von wenigstens 720 Zeilen, mindestens ein digitaler Eingang (DVI-D/-I oder HDMI), und eine Auflösung von 1280 × 720 Pixeln (Vollbilder) bzw. 1920 × 1080 Pixeln (Halbbilder). Ein Gerät das diesen Anforderungen gerecht wird kann hochauflösendes Fernsehen wiedergeben und verspricht ein gestochen scharfes Bilderlebnis.
 
";2;False;0;;;"Acer Aspire Timeline 1810TZ 11.6 Zoll Notebook ";acer-aspire-1810tz-412g32n-rot-295-cm-116-zoll-notebook;True;True;P-0830;;;False;0;False;;False;False;0;False;0;1;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;1;9999;False;False;0;1;1;0;False;1;10000;;False;False;False;False;547.9000;0.0000;0.0000;499.0000;41640;41820,9999884259;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40121,6691898148;"5;2095";37;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000527-acer-aspire-1810tz-412g32n-rot-295-cm-116-zoll-notebook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000528-acer-aspire-1810tz-412g32n-rot-295-cm-116-zoll-notebook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000529-acer-aspire-1810tz-412g32n-rot-295-cm-116-zoll-notebook.jpg;2;;True;ml;2.0000;1;;False;False;False;;;;;False;;;;;; -5;0;True;Canon PIXMA MP640 Multifunktionsgerät 3 in 1;"Canon PIXMA MP640 Multifunktionsgerät ";"
Canon PIXMA MP640 Multifunktionsgerät
 
 
3 in 1, Drucken, Kopieren, Scannen
 
 
Der PIXMA MP640 ist ein Multifunktionssystem der Spitzenklasse für exzellenten Fotodruck, schnellen Dokumentendruck und mit vielfältigen Scan- und Kopierfunktionen.
Dank WiFi- und Ethernet-Unterstützung kann er in ein kabelgebundenes und kabelloses Netzwerk integriert werden.

Multifunktionssystem: Fotodrucker, Farbscanner und Farbkopierer
Druckgeschwindigkeit: ca. 9,2 (SW) bzw. 8,1 (Farbe) ISO-Seiten/Min; einzelne Tintentanks
ca. 20 Sek. für den druck eines 10 x 15 cm Randlosprint
Automatischer Duplexdruck, doppelte Papierzufuhr und DVD/CD-Druck
Lieferumfang: PIXMA MP640, Netzkabel, Druckkopf, Tintentanks, DVD/CD-Halter, Kurzanleitung, CD mit Installations-Software und Benutzerhandbuch, Garantiekarte,
Druckmedien-Broschüre, Fotoglanzpapier Plus II PP-201, MP-101 zur Druckkopfausrichtung
";2;False;0;;;"Canon PIXMA MP640 ";canon-pixma-mp640-multifunktionsgeraet-3-in-1;True;True;P-2220;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;219.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40120,6418055556;22;25;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000523-canon-pixma-mp640-multifunktionsgerat-3-in-1.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000524-canon-pixma-mp640-multifunktionsgerat-3-in-1.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000525-canon-pixma-mp640-multifunktionsgerat-3-in-1.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Trekstor DataStation pocket x.u s ";Trekstor DataStation pocket x.u s 250 GB;"
Trekstor DataStation pocket x.u s 250 GB
 
 
Externe 2.5 Zoll Festplatte
Exklusives Aluminiumgehäuse für optimale Kühlung der Festplatte
Speichergröße 250 GB
Geeignet für das neue Windows® Vista
Lieferumfang: Festplatte, Nero BackItUp 2 Essentials, Software- / Treiber-CD, USB 2.0-Y-Anschlusskabel, Kurzanleitung, Transportetui
";2;False;0;;;"Trekstor DataStation pocket x.u s ";trekstor-datastation-pocket-xu-s;True;True;P-2640;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;89.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40120,6286921296;15;2;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000522-trekstor-datastation-pocket-xu-s.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Canon Digital IXUS 100 IS Digitalkamera silber;"Canon Digital IXUS 100 IS Digitalkamera silber ";"

Canon Digital IXUS 100 IS Digitalkamera silber

12 Megapixel, 3-fach opt. Zoom, 2,5"" Display, HDMI, SLIM
 
Die Digital Ixus 100 IS präsentiert sich im atemberaubend-exquisiten, nur 18,4 Millimeter flachen Edelstahlgehäuse. Sie ist in den vier Farben Silber, Schwarz, Gold und Rot erhältlich.

Ob großformatige Fotoprints oder gezielte Ausschnittvergrößerungen: Die hohe Auflösung von 12,1 Megapixeln sorgt für eine überzeugende Detailwiedergabe.
 
Für hohe Geschwindigkeit und exzellente Bildqualität mit brillanten Farben und minimiertem Bildrauschen steht der aktuelle Canon-Bildprozessor DIGIC 4.
12,1 Megapixel Sensor
3-fach optisches Zoom
Großes hochauflösendes 2,5 Zoll PureColor LCD II
Superschlank; HD-Movie und HDMI-Anschluß ¿ mehr Details im Film
 
Lieferumfang:
Digital IXUS 100 IS, Trageriemen, Akku, Akku-Ladegerät, USB-Kabel, Video-Kabel
";2;False;0;;;"Canon Digital IXUS 100 IS Digitalkamera ";canon-digital-ixus-100-is-digitalkamera-silber;True;True;P-1730;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;199.0000;199.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40119,9167824074;"56;2095";25;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000514-canon-digital-ixus-100-is-digitalkamera-silber.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000515-canon-digital-ixus-100-is-digitalkamera-silber.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000516-canon-digital-ixus-100-is-digitalkamera-silber.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Samsung N130-@nyNet 10,1 Zoll Netbook ";5 GB, 16 Zoll, 500 GB, AMD, 4;"
Samsung N130-@nyNet 10.1 Zoll Netbook  schwarz
 
Intel Atom N270 1.6GHz, 1GB RAM, 160GB HDD, Intel GMA 950, , Win 7 Starter
 
Mit dem N130 präsentiert Samsung Electronics ein preisgünstiges und leistungsstarkes Netbook der N-Serie. Ultraleicht und funktional arbeitet das N130 mit aktuellster Samsung Technologie und überzeugt durch Qualität, Design und Performance auf hohem Niveau. Das 1,26 kg leichte Netbook ist mit einem spiegelfreien 10,1-Zoll-Non-Gloss-Display ausgestattet. Mit einer Laufzeit von bis zu 6,5 Stunden gehört es zu den Langläufern im Netbook-Markt.
 
Flaches und elegantes Gehäuse-Design
Das N130 mit hochwertigen Komponenten und Materialien steckt in einem flachen, eleganten Design-Gehäuse. Mit seiner umfangreichen Funktionalität und gerade einmal 1,26 kg ist das N130 das leichteste Gerät seiner Klasse und bietet damit Mobilität auf höchstem Niveau.
 
Optimale Mobilität durch geringen Stromverbrauch
Das 10,1-Zoll-Non-Gloss-Display des N130 ist extrem energieeffizient und brilliert mit einem scharfen und hellen Bild ohne Spiegelungen sogar bei extremer Sonneneinstrahlung. Der geringe Stromverbrauch garantiert optimale Mobilität durch Samsungs führende Lithium-Ionen-Akku-Technik und ermöglicht eine außergewöhnliche Laufzeit von bis zu 6,5 Stunden.
 
Immer in Verbindung - mit WLAN
Schnellen Zugriff auf Internet und andere Inhalte gewährleistet das Netbook via 802.11b/g/n WLAN - jederzeit und überall. Darüber hinaus ist das Netbook mit einem eingebauten Mikrofon und Kopfhöreranschluss - beispielsweise für VoIP-Telefonie - ausgestattet. Mit drei USB 2.0-Anschlüssen und einem 3-in-1-Kartenleser erlaubt das N130 die Wahl zwischen zahlreichen Datenaustausch-Optionen. So lassen sich Informationen, Bilder, Musiktitel und Filme mit allen modernen Peripheriegeräten wie Kameras, externen Festplatten oder Audio/Video-Geräten blitzschnell austauschen. 
";2;False;0;;;"Samsung N130@nynet-N270BN 10.1 Zoll Netbook ";samsung-n130-nynet-101-zoll-netbook;True;True;P-0810;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;284.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40116,2153125;5;5;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000307-samsung-n130-nynet-101-zoll-netbook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000308-samsung-n130-nynet-101-zoll-netbook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000309-samsung-n130-nynet-101-zoll-netbook.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Asus EEE PC 1005HA-M 10,1 Zoll Netbook ";2 GB, 16 Zoll, 350 GB, Tantel, 4;"
Asus EEE PC 1005HA-M 10,1 Zoll Netbook mit Windows 7 Starter weiß
 
 
Langläufer: Eee PC 1005HA. Mit dem Eee PC 1005HA hat ASUS ein stylisches Geräte im Portfolio, das sich durch ihre lange Akkulaufzeit und ein mattes, nicht spiegelndes Display auszeichnen. Der Eee PC 1005HA-M inklusive Intel Atom N270 Prozessor kommt auf eine Akkulaufzeit von 8,5 Stunden. Die Geräte arbeiten mit dem Microsoft Windows 7 Betriebssystem und sind dadurch besonders intuitiv und komfortabel zu bedienen.
 
Das Betriebssystem Microsoft Windows 7
Mit Windows 7 stellt Microsoft ein Betriebssystem vor, das sich durch eine leichte Bedienung und einen ressourcensparenden Umgang mit der Hardware auszeichnet. Selbst auf Rechnern mit begrenzter Prozessorpower läuft das Betriebssystem mühelos. So benötigt der PC nur noch wenige Augenblicke zum Hochfahren und auf der übersichtlichen Taskleiste lassen sich anhand von Symbolen schnell die passenden Files erkennen. Spielend leicht wird auch die Verwaltung von Filmen, Bildern und Videos. Mithilfe der Bibliotheken lassen sich diese schnell organisieren. Und in punkto Sicherheit bringt das Betriebssystem einiges mit. Darunter die Benutzerkontensteuerung, die sich individuell konfigurieren lässt. 
 
Ehe PC 1005HA-M: Klasse Leistung zu unschlagbarem Preis
Der Eee PC 1005HA-M unterscheidet sich von seinem großen Bruder durch Prozessor, Akkukapazität sowie durch die integrierten Wireless Funktionen. Ausgestattet mit einem Intel Atom N270 Prozessor, einem 4400 mAh 6 Zellen Akku für bis zu 8,5 Stunden Laufzeit, WLAN 802.11n Standard sowie weiteren Top Merkmalen, überzeugt der Eee PC 1005HA-M zu einem unschlagbaren Preis.
 
Eee PC 1005HA-M: Funktionalität meets Design
Mit dem kompakten Eee PC 1005HA-M trägt ASUS seinem Anspruch, in den Produkten höchste Funktionalität mit formvollendetem Design zu verbinden, ein weiteres Mal Rechnung. So besticht der Eee PC durch sein elegantes und gleichzeitig unempfindliches Gehäuse, das mit klaren Linien und nach unten schmaler zulaufenden Kanten dem schlanken Design einer Muschel nachempfunden ist. 
  
Aber auch das Innenleben der Kleinen kommt ganz groß raus. Als gewohnt kontaktfreudig erweisen sich die Neulinge dank VGA Port für den Anschluss eines Monitors sowie drei USB 2.0 Schnittstellen, um Maus, Tastatur oder Digicam anzuschließen. Wer Bilder direkt von der SD oder MMC Speicherkarte auf den Eee PC übertragen möchte, nutzt den integrierten Kartenleser. Für das Speichern der Fotos stehen bei den Modellen eine 160 GB S-ATA Festplatte zur Verfügung. Die Modelle sind - wie alle Eee Familienmitglieder - ausgesprochen einfach zu bedienen. Das 10 Zoll WSVGA Display mit stromsparender LED-Hintergrundbeleuchtung sowie die große Tastatur, die zu 92% einer Standard Notebooktastatur entspricht, gewähren zusätzlichen Komfort. Für Chats oder Videokonferenzen hat ASUS die Minis zudem mit einer 1.3 Megapixel Web-/Videokamera sowie einem Mikrofon ausgestattet.
";2;False;0;;;"Asus EEE PC 1005HA-M 10,1 Zoll Netbook ";asus-eee-pc-1005ha-m-101-zoll-netbook;True;True;P-0800;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;291.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40115,7052199074;5;37;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000300-asus-eee-pc-1005ha-m-101-zoll-netbook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000301-asus-eee-pc-1005ha-m-101-zoll-netbook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000302-asus-eee-pc-1005ha-m-101-zoll-netbook.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Trekstor DataStation maxi g.u 1,5 TB ";"Trekstor DataStation maxi g.u externe Festplatte 1,5 TB ";"

Trekstor DataStation maxi g.u Externe Festplatte 1,5 TB

 
 
USB 2.0 inkl. Nero BackItUp 2 Essentials
 
 
 
Optimale Speicherplatzerweiterung
Die DataStation maxi g.u ist die perfekte Lösung für das
tägliche Backup oder die Speicherplatzerweiterung Ihres PCs.
Die externe 3,5“ Festplatte bietet ausreichend Platz
zum Speichern und Archivieren der heimischen Musik-
und Videosammlung, digitaler Fotos oder anderer Dateien. 
 Schnell und bedienungsfreundlich
Mit dem Hi-Speed USB 2.0 Anschluss bietet die
DataStation maxi g.u einen schnellen Datentransfer.
Die Festplatte ist zudem bereits vorformatiert und
ohne Treiber sofort betriebsbereit.
Unterstützt werden alle gängigen
Dateisysteme von Windows®, Linux® und Mac® OS X,
sowie die Betriebssysteme Microsoft
Windows® 2000 / XP/ Vista, Mac® OS X ab 10.3 und Linux® ab Kernel 2.6.x.
Die Festplatte wird über das mitgelieferte Netzteil mit Strom versorgt. 
Der Ein-/Ausschalter am Festplattengehäuse verhindert überflüssigen Stromverbrauch. 
Exklusives Aluminiumgehäuse
Das exklusive Aluminiumgehäuse der DataStation maxi g.u
sorgt für die optimale Kühlung der Festplatte,
so kommt die externe Festplatte
ohne Lüfter aus und ist leise während des Betriebs 
Inklusive Nero Software „BackItUp2 Essentials“
Die ebenfalls im Lieferumfang enthaltene
Nero Software rundet das Bild der mobilen, externen Festplatte perfekt ab.
Mit Nero BackItUp2 Essentials können Sie Backups Ihrer Daten sehr einfach planen.
So können einzelne Dateien oder ganze Laufwerke gesichert werden.
Um die Datenmenge gering zu halten, komprimiert die Software die Backups direkt „on the fly“.
Auf Wunsch lassen sich die gesicherten Daten auch per Passwortschutz vor unbefugtem Zugriff schützen.
";2;False;0;;;"Trekstor DataStation maxi g.u-externe Festplatte 1,5 TB ";trekstor-datastation-maxi-gu-15-tb;True;True;P-2630;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;139.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40101,7793981481;15;2;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000129-trekstor-datastation-maxi-gu-1tb.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"NAVIGON 2410 Navigationssystem inkl. TMC ";"NAVIGON 2410 Navigationssystem inkl. TMC ";"

NAVIGON 2410 Navigationssystem inkl. TMC

 
 
3,5"" Display, EU Kartenmaterial mit 40 Ländern, Fußgängernavigation im Hochformat
 
 
Fußgänger-Navigation
bringt Sie ohne Umwege ans Ziel, auch wenn Sie mal nicht im Auto unterwegs sind.
So können Sie z. B. unbekannte Städte ganz gezielt erkunden und finden auch die verstecktesten Plätze und Sehenswürdigkeiten.
Dabei halten Sie Ihr NAVIGON übrigens ganz bequem im Hochformat in einer Hand – und haben so die andere jederzeit frei.
 
NAVIGON Zielgerade
navigiert Sie nach dem Parken die letzten Meter zu Ihrem eigentlichen Ziel. Denn: Nicht vor jedem geplanten Ziel ist auch ein Parkplatz für Ihr Fahrzeug.
Deshalb lotst Ihr NAVIGON Sie sicher auf dem letzten Stück zu Fuß. Und findet auf dem Rückweg auch Ihr Auto für Sie wieder.
 
E-Kompass
Großstädte können auch zu Fuß sehr unübersichtlich sein. Damit Sie nicht mit den Himmelsrichtungen durcheinander kommen, unterstützt Sie im Fußgängermodus ein elektronischer Kompass.
So wissen Sie sofort, ob Sie nach links, rechts, oben oder unten laufen müssen. Beziehungsweise nach Westen, Osten, Norden oder Süden.
 
Clever Parking
hilft Ihnen bei der Parkplatzsuche. Kurz vor Ihrem Ziel zeigt Ihnen Clever Parking Parkplätze in der näheren Umgebung an.
In Deutschland, Österreich, Schweiz und Luxemburg werden Sie sogar über Parkgebühren und Öffnungszeiten informiert. So vermeiden Sie langes Suchen und sparen dabei Geld.
 
NAVIGON MyRoutes
Je nachdem, welcher Fahrertyp Sie sind, empfiehlt Ihnen NAVIGON MyRoutes die beste Route – zugeschnitten auf Ihren persönlichen Fahrstil, den Wochentag und die Tageszeit.
Darüber hinaus zeigt Ihnen Ihr NAVIGON bis zu zwei weitere Routen. Das schafft Transparenz. Sie entscheiden, ob Sie unserer Empfehlung folgen oder eine der Alternativen wählen.
 
TMC-Routeninfo
zeigt Ihnen im Fall einer Staumeldung eine Alternativroute mit aktualisierter Entfernung und Ankunftszeit.
Sie entscheiden, ob eine Umfahrung in Ihrem Fall sinnvoll ist oder ob Sie die ursprüngliche Route beibehalten wollen.
 
Lieferumfang
NAVIGON 2410, Kurzanleitung, KfZ-Ladekabel mit integrierter TMC Antenne, KfZ Halterung, USB-Kabel, Europa Kartenmaterial
";2;False;0;;;"NAVIGON 2410 Navigationssystem inkl. TMC ";navigon-2410-navigationssystem-inkl-tmc;True;True;P-2160;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;169.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40097,6045833333;68;14;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000299-navigon-2410-navigationssystem-inkl-tmc.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Adobe Premiere Elements 8;Adobe Premiere Elements 8 deutsch WIN;"

Adobe Premiere Elements 8 deutsch WIN


Mit Adobe® Premiere® Elements 8 erstellen Sie ohne Aufwand erstklassige Videos, die Sie mit professionellen Effekten bereichern und auf nahezu jedem Medium präsentieren können.
Dank eines leistungsfähigen und bedienungsfreundlichen Organizer behalten Sie den Überblick über Ihre Videos und Fotos.
 
Arbeiten Sie wie die Profis, indem Sie beispielsweise Grafiken und Effekte einfügen, die sich mit den zugehörigen Objekten zusammen bewegen.
Vielseitigkeit und Benutzerfreundlichkeit
Filmproduktion in wenigen Schritten
Filmerstellung per Drag-and-Drop
Zentrale Umgebung für Bearbeitung und Vorschau
Professionelle Spezialeffekte und Überblendungen
Aufwertung von Videos mit Musik
 
Systemanforderungen:
Prozessor mit 2 GHz und SSE2-Unterstützung; für HD oder Blu-ray: Prozessor mit 3 GHz; für AVCHD: Dual-Core-Prozessor
 
Microsoft® Windows® XP mit Service Pack 2, Windows Media Center, Windows Vista® oder Windows 7
Für Windows XP: 512 MB RAM (2 GB für HD-Bearbeitung einschließlich HDV, AVCHD oder Blu-ray)
Für Windows Vista and Windows 7: (1 GB RAM (2 GB für HD-Bearbeitung einschließlich HDV, AVCHD oder Blu-ray)
4,5 GB freier Festplattenspeicher
Farbmonitor mit 16-Bit-Grafikkarte
1024 x 768 Punkt Monitorauflösung mit 96 dpi oder geringer
Mit Microsoft DirectX 9 oder 10 kompatibler Sound- und Grafikkartentreiber
DVD-ROM-Laufwerk (kompatibler DVD-Brenner für die Erstellung von DVDs, kompatibler Blu-ray-Brenner für die Erstellung von Blu-ray Discs erforderlich)
 
";2;False;0;;;Adobe Premiere Elements 8;adobe-premiere-elements-8;True;False;P-3030;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;9200;False;False;0;1;1;0;False;1;10000;;False;False;False;False;112.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40097,5865856481;31;20;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000297-adobe-premiere-elements-8.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000298-adobe-premiere-elements-8.jpg;;2;;True;ml;1.0000;1;;False;False;False;;;;;False;;;;;; -5;0;True;Adobe Photoshop Elements 8;Adobe Photoshop Elements 8 deutsch WIN;"

Adobe Photoshop Elements 8 deutsch WIN

 

Adobe® Photoshop® Elements 8 ist die ideale Kombination aus Leistungsfähigkeit und Benutzerfreundlichkeit.
Verwalten Sie Ihre Bilder und Videos bequem zentral, machen Sie aus alltäglichen Motiven eindrucksvolle Kunstwerke, und gestalten Sie unverwechselbare Kreationen für Print und Web.
Jetzt können Sie perfekt ausgeleuchtete Bilder erstellen oder mit verschiedenen Bildgrößen experimentieren, ohne dass Verzerrungseffekte auftreten. Mit den erweiterten Suchfunktionen lassen sich Bilder wahlweise nach Qualität oder nach Motiv sortieren.

Vielseitigkeit und Benutzerfreundlichkeit
Praktischer Medien-Manager
Sekundenschnell retuschieren
Intuitive Anpassung von Farbe und Belichtung
Praktische Hilfestellungen
Herausragende Ergebnisse
Gelungene Präsentation im Web
Effiziente Umsetzung kreativer Ideen
 
Systemanforderungen:
Prozessor mit mindestens 1,6 GHz
Microsoft® Windows® XP mit Service Pack 2 oder 3, Windows Vista® oder Windows 7
1 GB RAM
2 GB freier Festplattenspeicher
Farbmonitor mit 16-Bit-Grafikkarte
1024 x 576 Punkt Monitorauflösung mit 96 dpi oder geringer
Mit Microsoft DirectX 9 kompatibler Grafikkartentreiber
DVD-ROM-Laufwerk
 
";2;False;0;;;Adobe Photoshop Elements 8;adobe-photoshop-elements-8;True;False;P-3020;;;False;0;False;;False;False;0;False;0;1;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;109.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40097,5787731481;31;20;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000295-adobe-photoshop-elements-8.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000296-adobe-photoshop-elements-8.jpg;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Garmin nüvi 255T Navigationssystem Europa ";"Garmin nüvi 255T Navigationssystem Europa inkl. TMC ";"
Garmin nüvi 255T Navigationssystem Europa inkl. TMC
 

3,5"" Touchscreen Display, PhotoNavigation, MicroSD-Kartenslot und ecoRoute 
 
Bedienerfreundliches Einsteigernavigationsgerät mit elegantem, ultra-schlankem Design und brillantem 3,5 (8,9cm Bilddiagonale)
Touchscreen Display + TMC Verkehrsfunkempfänger
Kartenmaterial für 40 Länder in West- und Osteuropa intern vorinstalliert ecoRoute:
reduziert den Kraftstoffverbrauch, CO2-Emissionen und schont die Umwelt, spart bares Geld und füllt die Reisekasse auf.
PhotoNavigation mit Garmin Connect: Sie können Sehenswürdigkeiten und Bilder herunterladen und als Ziel auswählen
Lieferumfang: Garmin nüvi 255T mit Kartenmaterial Europa, TMC Verkehrsfunkempfänger,
Saugnapfhalterung für die Windschutzscheibe, Armaturenhalterung, Schnellstartanleitung, KFZ-Anschlusskabel
 
";2;False;0;;;"Garmin nüvi 255T Navigationssystem Europa ";garmin-nuevi-255t-navigationssystem-europa;True;True;P-2090;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;129.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40096,6680208333;67;44;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000294-garmin-nuvi-255t-navigationssystem-europa.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Logitech Webcam C200 ";"Logitech Webcam C200 ";"
Sie suchen nach einem Basispaket für eine einfache, klare Videokommunikation? Die preisgünstige Logitech
Webcam C200 stellt Ihnen alle Funktionen zur Verfügung, die Sie für realitätsnahe Videogespräche benötigen. Sie bezahlen nicht für Zusatzfeatures, die Sie wahrscheinlich ohnehin nicht nutzen. Ihre Webkamera wird mit der Logitech Vid-Software geliefert, die Ihnen mit nur einem Mausklick das Führen von Videogesprächen ermöglicht – schnell, kostenlos, einfach. Der VGA-Sensor erfasst Ihre Live-Videobilder in natürlichen und realistischen Farben. Sie können auch Schnappschüsse machen, die per Software auf eine Auflösung von 1,3 Megapixeln hochgerechnet werden. Und das praktische eingebaute Mikrofon sorgt mit der Logitech RightSound- Technologie dafür, dass Ihre Stimme klar verständlich ist. Dank der Universalmonitorhalterung können Sie diese Webkamera problemlos an jedem Desktopmonitor oder Notebookrechner befestigen.
 

Seien Sie persönlich dabei - mit dem Basispaket für eine kostenlose und klare Videokommunikation
 
Ein Besuch bei Ihren Freunden und Verwandten in der Ferne ist ab sofort wesentlich einfacher. Mit der preiswerten Logitech Webcam C200 sind Sie nämlich direkt bei den Menschen, die Ihnen am Herzen liegen. Installieren Sie einfach Ihre Webkamera, und schon können Sie Ihr erstes Videogespräch führen. Dazu ist nur ein einfacher Mausklick erforderlich, wenn Sie die Vid-Software nutzen, die mit Ihrer Webkamera mitgeliefert wird. Plaudern Sie persönlich mit Ihren Enkeln in der Nachbarstadt – oder mit Ihrer besten Freundin am anderen Ende der Welt. Der VGA-Sensor sorgt dafür, dass Ihre Gesprächspartner Sie in ganz natürlichen Farben sehen. Und dank dem eingebauten Mikrofon mit der Logitech RightSound-Technologie, die störende Nebengeräusche herausfiltert, können sie jedes Wort aus Ihrem Mund deutlich verstehen. Wenn Sie ein praktisches Basispaket für Videogespräche suchen und auf komplizierte Zusatzfunktionen verzichten können, ist dies die richtige Webkamera für Sie.
 
Die wichtigsten Funktionen
 
Webkameras von Logitech - bessere Videoqualität kommt nicht von ungefähr
 
Sobald Sie Ihr erstes Videogespräch führen, wird Ihnen klar werden, warum Logitech die erste Wahl von Webkamera-Anwendern auf der ganzen Welt ist. Bei der Entwicklung jeder Webkamera ist das oberste Designziel von Logitech, eine erheblich klarere Bild- und Tonqualität als andere Webkameras zum gleichen Preis zur Verfügung zu stellen. Dabei geht es geht nicht nur um Features wie Qualität des Objektivs, Sensor-Auflösung und Software. Es geht viel mehr darum, wie alle diese Dinge ineinandergreifen, um Ihnen eine Videokommunikation mit mehr Komfort und Vergnügen zu ermöglichen.
   
Der VGA-Sensor zeigt Ihr wahres Ich
 
Nur weil Sie nicht so viel Geld ausgeben wollen, heißt das noch lange nicht, dass Sie auf Qualität verzichten müssen. Ihre Logitech-Webkamera bietet Ihnen Extras, die Sie bei einer so preisgünstigen Webkamera wahrscheinlich gar nicht erwarten würden. Dazu zählt ein Sensor, der Live-Videobilder mit echter VGA-Auflösung in realitätsnahen Farben aufnimmt. Keine grünlich-bleichen oder verschwommenen Gesichter. Ihre Gesprächspartner bekommen Ihr wahres, natürliches Ich zu sehen. 
Auflösung mit bis zu 1,3 Megapixeln – verschicken Sie brillante digitale Schnappschüsse
 
Sie möchten Ihre Webkamera auch noch anderweitig nutzen? Drücken Sie einfach auf den Schnappschussauslöser, um realitätsnahe Fotos aufzunehmen, die per Software auf 1,3 Megapixel hochgerechnet werden. Und da sich die Schnappschüsse schon auf Ihrem Rechner befinden, können Sie sie ganz einfach per E-Mail an Verwandte oder Freunde verschicken.   
 
Eingebautes Mikrofon mit geräuschdämpfender RightSound- Technologie
 
Sprechen Sie ganz natürlich, das eingebaute Mikrofon der Webkamera nimmt jedes Wort, jedes Lachen, jedes Flüstern auf. Die RightSound-Technologie filtert automatisch störende Hintergrundgeräusche heraus, sodass Sie Ihre Gespräche immer mit kristallklarer Tonqualität führen können. 
 
Vielseitige Universalhalterung für die Befestigung an jedem Desktop- oder Notebook-Rechner
 
Was das praktische Design anbetrifft, hat Logitech an alles gedacht. Die Webkamera lässt sich problemlos und sicher an LCD-Bildschirmen ebenso wie an ultraflachen Notebook-Monitoren befestigen. Die Halterung kann auch eingeklappt werden, sodass Sie die Kamera auf einer ebenen Oberfläche wie beispielsweise einem Regal über Ihrem Computer aufstellen können.   
 
Problemlose Videogespräche dank Unterstützung aller Instant-Messaging-Programme
 
 
Alles, was Sie für Videogespräche benötigen, ist die Webkamera, ein schneller Internet-Zugang und ein Videokommunikations-Programm. Wenn Sie Ihre Freunde und Verwandten schnell, einfach und kostenlos von Angesicht zu Angesicht sprechen wollen, empfehlen wir Ihnen Logitech Vid als Software der Wahl. Sie können aber auch andere IM-Programme vom Internet herunterladen. Im Gegensatz zu den Produkten manch anderer Anbieter funktionieren die Webkameras von Logitech mit allen Instant-Messaging-Programmen, die Sie nutzen und die Ihre Gesprächspartner verwenden. Sie können also ganz problemlos und ohne großen Aufwand Videogespräche führen.
 
Mit der Logitech Webcam C200 und kostenlosen Video-Anwendungen können Sie „persönlich vor Ort“ sein – in Ihrer Stadt oder an jedem anderen Fleck der Erde. 
 
 
";2;False;0;;;"Logitech Webcam C200 ";logitech-webcam-c200;True;True;P-2920;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;34.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40096,6475;"27;2095";11;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000290-logitech-webcam-c200.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000291-logitech-webcam-c200.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000292-logitech-webcam-c200.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Western Digital My Book 1 TB;"Western Digital BAAF0010HBK My Book Essential 1TB ";"
Western Digital BAAF0010HBK My Book Essential

1TB externe Festplatte 
 
Elegantes Design
Ihre gesamten Daten auf einen Blick und einfache Datei-Wiederherstellung
Passwortschutz und 256-bit Hardware basierte Verschlüsselung
Automatische, kontinuierliche Datensicherung für alle Computer in Ihrem Netzwerk
Lieferumfang: Western Digital My Book Essential 1TB externes Festplattenlaufwerk,
WD SmartWare-Software, USB-Kabel, Netzteil, Schnellanleitung
";2;False;0;;;"Western Digital My Book Essential Edition 1 TB ";western-digital-my-book-1-tb;True;True;P-2600;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;129.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40090,625150463;14;21;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000286-western-digital-my-book-1-tb.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Apple iPod Classic 160 GB schwarz;"Apple iPod Classic 160 GB schwarz ";"

Apple iPod Classic 160 GB schwarz

 
iPod classic: Freiraum -Und zwar jede Menge.
160 GB sind wirklich eine ganze Menge Platz. Da lässt sich eine komplette Mediathek locker unterbringen und überallhin mitnehmen.
 
Ein musikalisches Genie
Stellen Sie vor, Sie hören einen Song. Toll wären jetzt andere Titel, die gut dazu passen. Was machen Sie? Ganz einfach: Sie verwenden die neue Funktion ""Genius"". Diese findet die Songs in Ihrer Mediathek, die gut zusammenpassen. Sie erhalten eine Genius Wiedergabeliste, die Sie sofort anhören, sichern oder sogar aktualisieren können. Verlassen Sie sich also auf den Genius von iTunes, wenn Sie einen Mix wollen, auf den Sie selbst nicht gekommen wären.
 
Platz satt
Der iPod classic bietet mit seinen 160 GB Speicherkapazität Platz für bis zu 40.000 Songs, 200 Stunden Videos, 25.000 Fotos oder eine beliebige Kombination dieser Inhalte. Und mit bis zu 36 Stunden Batterielaufzeit beweist der iPod classic auch ganz schön viel Kondition.
 
Spaß auf Knopfdruck
Sie findeen immer ganz leicht genau das, was Sie sehen oder hören wollen. Mit dem Click Wheel können Sie mit ""Cover Flow"" Ihre Alben durchblättern, oder Sie stöbern über verschiedene Kategorien wie Wiedergabeliste, Künstler, Album oder Musikrichtung in Ihren Songs und Videos. Sie können natürlich auch nach einem bestimmten Titel oder Interpreten suchen. Lust auf einen neuen Mix? Klicken Sie einfach auf ""Zufällige Titel"".
 
Filme und Fernsehsendungen ansehen
Auf dem fantastischen 2,5"" Display kommen Videos richtig zur Geltung. Sie können im iTunes Store Filme kaufen oder ausleihen, Fernsehsendungen kaufen und Video-Podcasts laden. Dann können Sie alles mit Ihrem iPod classic synchronisieren und immer und überall ansehen.
 
 
Spiele auf dem iPod
Wenige Fingertipps, viele Stunden Spielspaß. Vortex, iQuiz und Klondike sind schon auf dem iPod classic vorinstalliert, im iTunes Store können Sie weitere dazukaufen, z. B. Cake Mania. Alle iPod Spiele sind speziell für die iPod Oberfläche optimiert.
 
Fotos zeigen
Ihre Fotos aus iPhoto auf einem Mac oder aus Adobe Photoshop Elements und Adobe Photoshop Album auf einem PC bekommen Sie mit iTunes auf den iPod classic. Sie können Diashows mit Musik und Übergängen auf dem iPod classic oder mit optional erhältlichen Apple Komponenten oder mit einem Composite-AV-Kabel sogar auf dem Fernseher zeigen.
 
Umweltverträglichkeit
Der iPod classic steht für das kontinuierliche Engagement von Apple in puncto Umweltschutz. Die folgenden Merkmale tragen zu einer geringen Umweltbelastung bei:
 
    Arsenfreies Displayglas
    Ohne bromhaltige Flammschutzmittel
    Display mit LED-Hintergrundbeleuchtung ohne Quecksilber
    Frei von PVC
    Recyclingfähiges Gehäuse aus Aluminium und Edelstahl
 
Produktbeschreibungen
Freiraum. Und zwar jede Menge. 160 GB sind wirklich eine ganze Menge Platz. Da lässt sich eine komplette Mediathek locker unterbringen und überallhin mitnehmen.
 
> Highlights
- Click Wheel
- Frequenzbereich: 20 Hz bis 20.000 Hz
- Weitere unterstützte Audioformate: Protected AAC (aus dem iTunes Store), MP3 VBR, Audible (Formate 2, 3, 4, Audible Enhanced Audio, AAX und AAX+), Apple Lossless und WAV
- Platz für bis zu 40.000 Songs im 128 KBit/Sek. AAC-Format
- Platz für bis zu 25.000 vom iPod anzeigbare Fotos
- Platz für bis zu 200 Stunden Videomaterial
- Speichert Daten auf einer USB-Festplatte
- Akkuladezeit: ca. 4 Std. (schnelles Laden auf 80%ige Kapazität in 2 Std.)
 
> Grundeigenschaften
- Breite: 103.5 mm
- Höhe: 61.8 mm
- Tiefe: 10.5 mm
- Gewicht: 140.0 g
- Farbe: Schwarz
 
> Wiedergabeformate Audio
- AAC
- MP3
- WAV
 
> Akku
- Akkutyp: Li-Ion
 
> Display
- Displaytechnologie: LCD
- 2.5- Display
- Bilddiagonale: 6.35 cm
- Auflösung Breite: 320 Pixel
- Auflösung Höhe: 240 Pixel
- Hintergrundbeleuchtung: ja
 
> Speicher
- Speicherkapazität 160 GB
 
> Anschlüsse
- USB
- USB-Standard 2.0
 
> Audio-Anschlüsse
- Headsetanschluss: 3,5 mm Klinke
- ipod-Anschluss via IPOD Connector
 
> Lieferumfang
- iPod classic
- Apple Earphones
- USB 2.0 Kabel
- Dock-Adapter
- Dokumentation
 
> Umweltverträglichkeit
Der iPod nano steht exemplarisch für das Engagement von Apple in puncto Umweltschutz. Die folgenden Merkmale des iPod nano tragen zu seiner geringeren Umweltbelastung bei:
- Arsenfreies Glas
- Frei von bromhaltigen Flammschutzmitteln
- Frei von Quecksilber
- Frei von PVC
- Besonders recyclingfähig
 
";2;False;0;;;Apple iPod Classic 120 GB schwarz;apple-ipod-classic-160-gb-schwarz;True;True;P-1400;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;239.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40089,850162037;50;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000284-apple-ipod-classic-160-gb-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000285-apple-ipod-classic-160-gb-schwarz.jpg;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Logitech MK300 schnurlose Tastatur + Maus schwarz ";"Logitech MK300 schnurlose Tastatur + Maus schwarz ";"

Logitech MK300 schnurlose Tastatur + Maus schwarz
 

 
Kabellose Technologie für eine schnelle und zuverlässige Verbindung, die sofort einsatzbereit ist
Sondertasten und programmierbare F-Tasten
Flüssigere und reaktionsschnellere Abtastung als herkömmliche optische Mäuse
Automatischer Energiesparmodus
 
Lieferumfang:
Logitech MK300 Tastatur schnurlos, Logitech MK300 Maus schnurlos, USB-Empfänger, Batterien vom Typ AA, Handbuch, CD mit Software.
";2;False;0;;;;logitech-mk300-schnurlose-tastatur-maus-schwarz;True;True;P-2800;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;49.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40081,7438194444;21;11;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000513-logitech-mk300-schnurlose-tastatur-maus-schwarz.jpg;;;1;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Samsung NC10 anyNet 10,2 Zoll Netbook;"Samsung NC10 anyNet 10,2 Zoll Netbook schwarz ";"
Samsung NC10 anyNet10,2"" Netbook

Intel Atom N270 1.6GHz, 1GB RAM, 160GB HDD, Intel GMA 950 XP Home
 
NC10-anyNet: Entwickelt für das ""mobile Leben"". Entwickelt für höchste Ansprüche in innovativem Design. Das ultrakompakte und leichte Gehäuse bietet eine Reihe von praktischen Features, die das mobile Leben vereinfachen. Brillante Technologie angepasst an das rasante und digitale Leben für noch mehr Mobilität.
 
Schlankes Design
Mit einem optimierten 10,2 Zoll Breitbild Display für ein makelloses visuelles Erlebnis, ist das schlanke NC10 lediglich 1,19 cm hoch und passt nahezu in alle Taschen. Das widerstandsfähige Gehäuse bietet ein Maximum an Tragekomfort und Verlässlichkeit sowie hochwertiger Ergonomie und Stil.
 
Videokonferenz
Ob Videokonferenzen oder Live Messaging - die integrierte 1,3 Megapixel Kamera lässt sie noch leichter mit Freunden, Familie und Kollegen in Kontakt bleiben. Die Kamera verbindet die Auflösung und die Bildqualität einer Fotokamera mit der nachhaltig hohen Bildfrequenz einer Videokamera.
 
Robustes Gehäuse, langlebig und verlässlich
Fühlen Sie sich sicher mit dem robusten Protect-o-Edge Gehäuse, das für Langlebigkeit und Verlässlichkeit steht. Eine aufwendige Serie von 54 Qualitätstests, die von schnellen Temperaturwechseln bis zu elektrischen Überspannungen reichen, gewährleistet neue Standards in Punkto Belastbarkeit und Ausdauer.
 
Antibakterielle Tastatur
Die SilverNano Technologie beschichtet die Tastatur mit nano-kleinen Silberionen, die das Überleben und die Neuentstehung von Bakterien verhindern. Innerhalb von 24 Stunden werden 99,9% aller Bakterien abgetötet und es entsteht eine hygienische Arbeitsatmosphäre.
 
Leichtgewicht
Als eines der weltweit leichtesten 10,2 Zoll Mini Notebooks seiner Klasse, mit einem Gewicht von nur 1,45 kg, ist das NC10 voll bepackt mit neuester Technologie und garantiert dabei maximale Mobilität und Leistung.
  
Vollständige Notebook-Tastatur
Die vollständige Notebook-Tastatur bietet optimalen Schreibkomfort. Ergonomisches Design und optimierte Tastenabstände machen das Arbeiten und Kommunizieren angenehmer und ermöglichen schnelleres sowie fehlerloses Schreiben.
 
Voll ausgestattet für einfachen Datenaustausch
Einfacher Datenaustausch dank einer Vielzahl an Anschlussmöglichkeiten, inklusive einem Kartenleser und drei USB-Anschlüssen, so dass Sie problemlos Bilder, Filme und Daten auf und von nahezu allen modernen Kameras, periphären oder audiovisuellen Geräten transferieren können.
";2;False;0;;;;samsung-nc10-anynet-102-zoll-netbook;True;True;P-0860;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;329.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40066,9226388889;6;5;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000511-samsung-nc10-anynet-102-zoll-netbook.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000512-samsung-nc10-anynet-102-zoll-netbook.jpg;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Casio EXILIM EX-Z2 Digitalkamera schwarz;"Casio EXILIM EX-Z2 Digitalkamera schwarz ";"
Casio EXILIM EX-Z2 SR Digitalkamera schwarz
 
12 Megapixel, 3-fach opt. Zoom, 2,7"" Display


Die EX-Z2 versteckt in ihrem flachen Designgehäuse leistungsstarke 12,1 Megapixel.
Der CCD-Chip mit 12,1 Megapixel erlaubt nicht nur brillante Fotos zu machen, sondern auch Bildausschnitte zu bearbeiten, zu vergrößern und im Wunschformat auszudrucken – bei hervorragender Qualität und ohne Verlust von Bildinformationen.
 
12,0 Megapixel CCD-Chip
3fach optischer Zoom, 4fach digitaler Zoom
6,9 cm (2.7 Zoll) Wide Screen TFT- Farbdisplay
23 BEST SHOT Programme, Gesichtserkennung, Selbstauslöser, Speicherkartenslot für SD-/SDHC, MMC-/MMCplus und Eye-Fi Wireless Speicherkarten
 
Lieferumfang:
Digitalkamera, Akku, Ladegerät, USB-Kabel, AV-Kabel, Trageriemen, Grundlegende Referenz, CD-ROM
";2;False;0;;;"Casio EXILIM EX-Z2 SR Digitalkamera ";casio-exilim-ex-z2-digitalkamera-schwarz;True;True;P-1750;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;149.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40064,7887268519;"57;2095";9;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000499-casio-exilim-ex-z2-digitalkamera-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000500-casio-exilim-ex-z2-digitalkamera-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000501-casio-exilim-ex-z2-digitalkamera-schwarz.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Samsung Syncmaster P2250 21,5 Zoll TFT Monitor schwarz;"Samsung Syncmaster P2250 21,5 Zoll TFT Monitor schwarz ";"
Samsung Syncmaster P2250 21,5 Zoll TFT Monitor schwarz

DVI ,Kontrast 50000:1, 2ms Reaktionszeit

DieSyncMaster 50er Serie überzeugt mit schlichtem Design und moderner Technik.
Der elegant schmale Rahmen in Verbindung mit dem dezenten roten Farbverlauf macht diese Modelle zu einem echten Blickfang.
Das praktische 16:9-Format bietet eine Full HD Auflösung mit 1.920 x 1.080 Pixel.
Das sehr hohe dynamische Kontrastverhältnis von 50.000:1 und die schnelle Reaktionszeit von nur 2 ms (G/G) sorgen
stets für klare und detailreiche Bilder - auch bei schnell bewegten Bildinhalten.
Das praktische 16:9-Widescreen-Format ermöglicht ein noch angenehmeres Arbeiten bei gleichzeitiger Steigerung Ihrer Produktivität.
Das Breitbildformat entspricht dem natürlichen Sichtfeld des Betrachters. Somit haben Sie immer alles im Blick, ohne auf wichtige Informationen verzichten zu müssen.
Dieses SyncMaster Large Format Display verfügt über ein Full HD-Panel mit einer nativen Auflösung von 1.920 x 1.080 Pixel.
Somit können Bildinhalte im 1.080p-Format, der derzeit besten HD-Auflösung, wiedergegeben werden. 
Genießen Sie beste Bildqualität mit hoher Bildschärfe und Detailreichtum selbst in dunklen Szenen.
Mit einem dynamischen Kontrast von 50.000:1 werden Sie jedes Detail auf dem Bildschirm erkennen können.
Lieferumfang: Monitor, Signalkabel, Netzkabel, Treiber CD, Handbuch (CD)
";2;False;0;;;"Samsung Syncmaster P2250 21,5 Zoll ";samsung-syncmaster-p2250-215-zoll-tft-monitor-schwarz;True;True;P-2470;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;219.9000;219.9000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40048,6219907407;9;5;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000376-samsung-syncmaster-p2250-215-zoll-tft-monitor-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000377-samsung-syncmaster-p2250-215-zoll-tft-monitor-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000378-samsung-syncmaster-p2250-215-zoll-tft-monitor-schwarz.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Panasonic DMR EH 595 EG K DVD-/HDD-Rekorder 250 GB ";"Panasonic DMR EH 595 EG K DVD-/HDD-Rekorder 250 GB ";"

Panasonic DMR EH 595 EG K DVD-/HDD-Rekorder 250 GB

  
HDMI, DivX-zertifiziert, USB 2.0
 
  
Die Rekorder DMR-EH595 zeigen sich als wahre Alleskönner und zeichnen auf Festplatte oder DVD auf.
Sie verarbeiten alle gängigen DVD-Formate wie DVD-RW, -R (DL), DVD+RW/+R (DL) sowie DVD-RAM. Außerdem können CDs, CD-R/-RWs sowie MP3- und JPEG-Daten sowohl von DVD als auch CD abgespielt werden.
Die integrierte Festplatte erlaubt die Aufzeichnung von Fernsehprogrammen. Somit ist auch bei längerer Abwesenheit genügend Platz für die Lieblingsserie vorhanden.
Dank des integrierten, elektronischen Programmführers Gemstar Guide Plus+ erfolgen die Programmauswahl und Timerprogrammierung kinderleicht und intuitiv.
Die übersichtliche Darstellung des Fernsehprogramms bietet neben einer Genre-Auswahl zusätzlich eine gezielte Suche nach Stichworten.
So kann beispielsweise direkt nach Schauspielern, Themen oder Sportarten gesucht werden.
Neben dieser Funktion arbeiten die neuen Rekorder mit einer automatischen Kapitelerstellung bei der Aufzeichnung.
Dadurch können während der anschließenden Wiedergabe unerwünschte Programmsequenzen auf Knopfdruck übersprungen oder eine Szene blitzschnell gefunden werden.
Mit Pause Live TV kann zudem das laufende Fernsehprogramm jederzeit mit einem Druck auf die Pause-Taste angehalten und zu einem späteren Zeitpunkt weitergeschaut werden.
Dank Quick Start-Funktion sind die Rekorder innerhalb einer Sekunde einsatzbereit, so dass kein Film und keine Aufzeichnung verpasst werden.

Multiformat-DVD-Festplatten-Kombination
Intuitive Benutzerführung
Neben der Aufnahme des Fernsehprogramms überzeugen die neuen Rekorder als digitales Fotoalbum sowie Musik-Jukebox
Elektronische Programmführer Guide Plus+ mit Suchfunktion
Umfangreiche Anschlussmöglichkeiten
";2;False;0;;;Panasonic DMR EH 595 EG K;panasonic-dmr-eh-595-eg-k-dvd-hdd-rekorder-250-gb;True;True;P-1800;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;379.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40046,702650463;63;12;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000375-panasonic-dmr-eh-595-eg-k-dvd-hdd-rekorder-250-gb.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Garmin Freizeitguide Deutschland ";"Garmin Freizeitguide Deutschland ";"

Garmin Freizeitguide Deutschland

 
 
Wander- und Freizeitkarten von 21 Regionen 



Freizeit- und Wanderkarten von 21 Nationalparks und Freizeitregionen vom Bayrischen Wald bis zur Insel Rügen im Maßstab 1:25.000 (Auflistung der Regionen auf www.garmin.de)
Kompatibel mit allen aktuellen Garmin nüvi-Straßennavigationsgeräten und kartenfähigen Outdoor-GPS Geräten
Sonderziele (POIs) wie Freizeitparks, Schlösser, Burgen, Denkmäler, Museen, Zoos, Bäder und Thermen können direkt angesteuert werden
Micro SD Karte kann einfach in den Kartenslot eingeschoben werden - Installation oder Freischaltung entfällt
Lieferumfang: Micro SD Karte mit Freizeitguide Deutschland
";2;False;0;;;;garmin-freizeitguide-deutschland;True;True;P-2080;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;29.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40041,5175231481;"67;2095";44;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000364-garmin-freizeitguide-deutschland.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Garmin Nüvi 1490 Tpro Navigationssystem Europa ";"Garmin Nüvi 1490 Tpro Navigationssystem Europa ";"

Garmin Nüvi 1490 Tpro Navigationssystem Europa

 
 
 
5"" Touchscreen-Display, TMC Pro, ecoRoute, Fußgänger- und PhotoNavigation, Bluetooth
 
 
 
Mobile Navigation ohne Grenzen im Großformat, im ultra-flachem Design an die Bedürfnisse professioneller Anwender ausgerichtet
Übersichtliche und einfache Navigation im 5 Zoll Display mit Fahrspurassistent und 3D-Kreuzungsansicht,
TMC Pro Europa Premium Verkehrsfunkempfänger
Kartenmaterial für 41 Länder in West- und Osteuropa intern vorinstalliert;
Inklusive ecoRoute die Garmin Spritspar-Funktion und echter Fußgängernavigation mit optionalen CityXplorer Stadtplänen für Bus und Bahn
Lieferumfang: Garmin nüvi 1490Tpro mit Kartenmaterial Europa, KFZ-Anschlusskabel mit TMC Pro-Verkehrsfunkempfänger,
Saugnapfhalterung für die Windschutzscheibe, Armaturenhalterung, Schnellstartanleitung
";2;False;0;;;"Garmin Nüvi 1490Tpro Navigationssystem Europa ";garmin-nuevi-1490-tpro-navigationssystem-europa;True;True;P-2070;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;289.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40041,5110416667;67;44;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000363-garmin-nuvi-1490-tpro-navigationssystem-europa.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Garmin nüvi 255WT Navigationssystem Europa ";Garmin nüvi 255WT Navigationssystem Europa inklusive TMC;"

Garmin nüvi 255WT Navigationssystem Europa

inklusive TMC, 4,3"" Touchscreen Display, PhotoNavigation, SD-Kartenslot und ecoRoute
 
Bedienerfreundliches Einsteigernavigationsgerät mit elegantem, ultra-schlankem Design und brillantem 4,3“ großem Touchscreen Display + TMC Verkehrsfunkempfänger Kartenmaterial für 40 Länder in West- und Osteuropa intern vorinstalliert; ecoRoute: reduziert den Kraftstoffverbrauch, CO2-Emissionen und schont die Umwelt, spart bares Geld und füllt die Reisekasse auf. PhotoNavigation mit Garmin Connect: Sie können Sehenswürdigkeiten und Bilder herunterladen und als Ziel auswählen Lieferumfang: Garmin nüvi 255W mit Kartenmaterial Europa, + TMC Verkehrsfunkempfänger (=WT), Saugnapfhalterung für die Windschutzscheibe, Armaturenhalterung, Schnellstartanleitung, KFZ-Anschlusskabel
";2;False;0;;;"Garmin nüvi 255WT Navigationssystem Europa ";garmin-nuevi-255wt-navigationssystem-europa;True;True;P-2060;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;169.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40041,5046064815;67;44;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000362-garmin-nuvi-255wt-navigationssystem-europa.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Canon PowerShot SX200 IS ";Canon PowerShot SX200 IS;"

Canon PowerShot SX200 IS

12 Megapixel, 12-fach opt. Zoom, 3"" Display

Das neue Super-Zoom-Modell unter den Canon PowerShot-Digitalkameras zeigt große Stärke im kompakten Format:
28 Millimeter-Weitwinkelobjektiv, 12-fach optischen Zoom, DIGIC-4-Bildprozessor und starke 12,1 Megapixel machen die PowerShot SX200 IS zu einem idealen Reisebegleiter.
Für Spitzenqualität können Movieclips in High Definition mit 720p und 30 B/s aufgezeichnet und über die integrierte HDMI™-Schnittstelle auf einem HDFernseher wiedergegeben werden.
Ein Aufnahmemodus für die vollständig manuelle Steuerung bringt ambitionierten Fotografen kreative Freiheit pur.
 
Die Leistungsstärke des neuen DIGIC-4-Bildprozessors führt zu einer optimierten Motion- und Face-Detection-Technologie.
Motion Detection unterscheidet Kameraverwacklungen von bewussten Bewegungen des Motivs und stimmt in Kombination mit dem Servo AF darauf die Einstellungen der Kamera zur Minimierung von Verwacklungsunschärfen ab.
Face Detection erkennt Gesichter im Motiv, auf die die Kamera dann kontinuierlich scharf stellt.
Starke Pluspunkte bei der Canon Face Detection sind der FaceSelf-Timer für Gruppenfotos, in denen der Fotograf bequem mit auf das Bild kommt, und die Rote-Augen-Korrektur.
 
Als weitere Technologie-Komponente spielt die innovative Canon-i-Contrast- Technologie ihre Stärken bei Bildern mit dunklen Bildbereichen aus:
Sie erhöht den Kontrast ausschließlich in diesen Bildpartien, anstatt lediglich die Gesamthelligkeit zu steigern, was zu überbelichteten Bildern führen würde. Der Canon-DIGIC-4- Prozessor ist zudem die Basis für schnelle Reaktionszeiten, effizientes Pufferspeicher-Handling und minimiertes Bildrauschen.
 
Manche Motive muss man einfach in bewegten Bildern festhalten:
Dafür hat die PowerShot SX200 IS einen Movie-Modus, in dem Movieclips sogar in High- Definition-Auflösung (720p) aufgezeichnet werden.
Ideal für die Wiedergabe der Clips auf einen High-Definition-Fernseher ist die integrierte HDMI™-Schnittstelle für den Anschluss der Kamera.
Das 3,0 Zoll große LC-Display der Kamera macht nicht nur Bildkomposition und Bildprüfung angenehm einfach, der große Betrachtungswinkel ist auch ideal für das direkte Betrachten von Bildern und Movieclips.
Die neue Benutzeroberfläche verfügt zudem über eine intelligente Funktion zur Einblendung praktischer Tipps und Tricks für die unterschiedlichen Einstellungen und ihre Auswirkungen auf die Aufnahmen.
 
Lieferumfang:
PowerShot SX200 IS, Trageriemen, Akku, Akku-Ladegerät, USB-Kabel, Video-Kabel
";2;False;0;;;Canon PowerShot SX200 IS;canon-powershot-sx200-is;True;True;P-1720;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;259.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40039,860474537;"56;2095";25;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000351-canon-powershot-sx200-is.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000352-canon-powershot-sx200-is.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000353-canon-powershot-sx200-is.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Philips DLA 1619 H/10 Neopren-Tasche für iPod Shuffle ";"Philips DLA 1619 H/10 Neopren-Tasche für iPod Shuffle schwarz ";"

Philips DLA 1619 H/10 Neopren-Tasche für iPod Shuffle schwarz

Armband, Sichtfenster und Gürtel-Clip
 
Ob für Sport oder Erholung, Ihr iPod ist immer dabei. Dafür ist das Action Jacket die allumfassende Lösung.
Verwenden Sie das verstellbare Armband beim Sport und bewahren Sie den iPod shuffle nach dem Sport in der schützenden Hülle auf.
 
  • Aktiver Schutz
  • Durchsichtiges Fenster zum Schutz des Bildschirms
  • Neopren schützt vor Schweiß
  • Vielseitige Positionierung
  • Anpassbares Sportarmband
  • Das anpassbare Sportarmband ist dehnbar und passt sich so unterschiedlichsten Größen an. Es ist mit einem
  • Klettverschluss versehen, sodass Ihr Gerät bei jeder Aktivität sicher verstaut ist.
  • Sichtfenster für das Display
  • Beim Sport schützt dieses durchsichtige Fenster den Bildschirm des Geräts und ermöglicht gleichzeitig die
  • Bedienung des Geräts.
  • Feuchtigkeitsbeständiges Neopren
  • Diese Neoprentasche bietet eine gepolsterte, feuchtigkeitsbeständige Schicht für Ihr Gerät und schützt es beim
  • Sport vor Schweiß und den Elementen.
";2;False;0;;;"Philips DLA 1619 H/10 Neopren-Tasche für iPod Shuffle ";philips-dla-1619-h10-neopren-tasche-fuer-ipod-shuffle;True;True;P-1520;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;24.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40035,8124652778;51;6;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000350-philips-dla-1619-h10-neopren-tasche-fur-ipod-shuffle.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Hama MP3-Tasche iPod nano 5G;Hama MP3-Tasche iPod nano 5G Transparent;"
Hama MP3-Tasche iPod nano 5G Transparent 

 
robuste, passgenaue Silikontasche; perfekte Passform, sitzt wie eine zweite Haut;
Ausstattung: Aussparungen für Bedienelemente und Anschlüsse;
3D-Sticker für bessere clickwheel Steuerung; abnehmbares Trageband
Displayschutzfolie; Serie: Sport Case; Farbe: Transparent; Material: Silikon;
Medium: MP3-Player; Typ: Fenstertasche; für MP3-Marke: für iPod Nano 5G
";2;False;0;;;;hama-mp3-tasche-ipod-nano-5g;True;True;P-1510;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;14.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40035,80875;"51;2095";18;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000349-hama-mp3-tasche-ipod-nano-5g.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Panasonic DMR EH 695 EG DVD- und Festplatten-Rekorder 320 GB;"Panasonic DMR EH 695 EG DVD- und Festplatten-Rekorder 320 GB ";"
Panasonic DMR EH 695 EG DVD- HDD-Rekorder 320 GB

 
HDMI, SDHC-Kartenslot, USB 2.0

Der neue DIGA DVD-Recorder DMR-EH695 mit analogen Kabeltuner steht für hervorragende Aufnahme- und Wiedergabequalität, Musikgenuss sowie ein Maximum an Kompatibilität.
 
Auf die 320 GB Festplatte können bis zu 567 Stunden (EP Modus) oder aufgrund eines sehr guten Encoders bis zu 284 Stunden Aufnahmekapazität in DVD Qualität (LP-Modus) gespeichert werden.
 
Die Super Multi Format Aufnahmefähigkeit des DMR-EH695 verarbeitet alle DVD Formate [DVD-RAM, -RW, -R, -R (DL), +RW, +R, +R (DL)] und spielt neben diesen Formaten zusätzlich JPEG, MP3, WMA und DivX Daten ab. Auf die integrierte ""Jukebox"" lassen sich schnell und einfach Ihre Musik CDs in 12-facher Kopiergeschwindigkeit (6min.)
in unkomprimiertem LPCM auf die Festplatte kopieren.
 
Die Album, Interpreten und Titelinformationen sind bereits auf der vorinstallierten Gracenote-Datenbank auf der Festplatte hinterlegt, sodass eine lästige Eingabe entfällt.
 
Über den USB Eingang können Sie Ihre MP3/WMA-Musikinhalte, JPEG Bilder oder MPEG2 Filme vom Camcorder ebenfalls auf die Festplatte kopieren oder abspielen. Neben diesen Formaten können auch DivX-Dateien abgespielt werden. Ebenfalls in Front bietet ein SDHC Slot die Möglichkeit, HD-JPEG oder MPEG2 Aufnahmen auf die Festplatte zu kopieren oder abzuspielen.
 
Der DMR-EH695 skaliert jedes Bildmaterial über die HDMI-Schnittstelle in eine maximale HDTV Auflösung mit 1080 Zeilen (Full HD).
 
Die neue praktische VIERA LINK Funktion, ausschließlich über HDMI mit den VIERA Flachbildschirmen nutzbar, bietet Ihnen komfortable Bedienung aller Panasonic Geräte mit nur einer Fernbedienung! Einfach, schnell und problemlos.
 
HDMI-Ausgang (HDMI Ver. 1.3)
USB-Anschluss (USB 2.0 High Speed)
SD-HC Karten-Slot
DV Eingang (IEEE1394/iLink)
Komponentenausgang (YUV)
2x Scart-Anschluss
Front-AV (S-Video/Video/Audio-IN)
S-Video Ausgang (Hosiden)
Video-Ausgang (Cinch)
Audio Ausgang (Cinch)
Optischer Digitalausgang (PCM, Dolby Digital, DTS, MPEG)
 
Lieferumfang:
Panasonic DMR-EH695EGK, Fernbedienung
";2;False;0;;;"Panasonic DMR EH 695 EG DVD- und Festplatten-Rekorder ";panasonic-dmr-eh-695-eg-dvd-und-festplatten-rekorder-320-gb;True;True;P-1790;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;419.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40035,2792476852;64;12;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000348-panasonic-dmr-eh-695-eg-dvd-und-festplatten-rekorder-320-gb.jpg;;;3;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Qualitätsakku für Canon EOS 450D, 500D und 1000D ";"Qualitätsakku für Canon EOS 450D, 500D und 1000D Typ: Lithium-Ion-Akku ";"

Qualitätsakku für Canon EOS 450D, 500D und 1000D

Typ: Lithium-Ion-Akku
 
Leistungsstark - hohe Qualität und doch günstig
Dieser Qualitätsakku zeichnet sich durch seine Langlebigkeit und Zuverlässigkeit aus und steht dem Original von Canon LP-E5 in nichts nach.
Dieser Akku passt auch in den Batteriegriff Canon BG-E5. Der Akku ist mit einem Chip ausgestattet, welcher Überladung und Überhitzung verhindert.
 
Technische Details
• Typ: Lithium-Ion-Akku
• Spannung: 7,4v
• Kapazität: 1080mAh
• Gewicht: 50g
• Überladungs-/Überspannungsschutz
";2;False;0;;;Qualitätsakku für Canon EOS 1000D;qualitaetsakku-fuer-canon-eos-450d-500d-und-1000d;True;True;P-1710;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;29.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40035,2271412037;56;25;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000347-qualitatsakku-fur-canon-eos-450d-500d-und-1000d.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Logitech V150 Laser Mouse ";"Logitech V150 optische Notebook Maus schnurgebunden silber ";"Logitech V150 optische Notebook Maus schnurgebunden silber
 
 
 
Plug & Play: Die Maus muss nur an einem USB-Anschluss angeschlossen werden und ist sofort einsatzbereit.
Laserabtastung: Erleben Sie Laser für präzise, flüssige Abtastung auf fast jeder Oberfläche
Tilt Wheel Plus Zoom¿: Horizontale Bildläufe. Vergrößern und verkleinern Sie mühelos Fotos und Tabellen.
Handgerechte Form: Komfort für Rechts- und Linkshänder.
Besonders kompaktes Design: Praktisch für unterwegs. ";2;False;0;;;"Logitech V150 Laser Mouse for Notebooks ";logitech-v150-laser-mouse;True;True;P-2790;;;False;0;False;;False;False;0;False;0;1;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;29.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40028,639212963;21;11;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000346-logitech-v150-laser-mouse.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Panasonic DMP-BD60EG-K Blu-ray Player;"Panasonic DMP-BD60EG-K Blu-ray Player schwarz ";"

Panasonic DMP-BD60EG-K Blu-ray Player schwarz

 
HDMI, Upscaling 1080p, USB 2.0

 
 Glänzt als wahre Allround-Unterhaltunskünstler
Moderne Schnittstellen wie SD/SDHC-Slot und USB-Eingang mit Multimediamöglichkeiten
Über den Ethernet-Port Zugriff auf den I/P-Service VIERA Cast
Z.B. YouTube-Videos und Fotos über den Online-Bilderdienst Picasa ansehen
Zahlreiche Komfortmerkmalen wie BD-Live und Bonus View
Wiedergabe-Formate: Blu-ray Video, Blu-ray Disc (BD-R), Blu-ray Disc wiederbeschreibbar (BD-RE), DVD-Video, DVD+R, DVD-R, DVD+RW, DVD-RW, DVD+R DL, DVD-R DL, DVD-RAM,
CD-Audio, CD-R, CD-RW, MP3, DivX, Foto-Formate JPEG
Audio: Dolby Digital Plus, Dolby TrueHD, DTS-HD, MPEG2
Anschlüsse: Audio-Ausgang, Video-Ausgang, Video-Farbkomponenten-Ausgang (YPbPr / YUV), Digital-Ausgang Optisch, Speicherkarten-Steckplatz, HDMI, USB, Netzwerk
Farbe: schwarz
";2;False;0;;;Panasonic DMP-BD60EG-K Blu-ray Player;panasonic-dmp-bd60eg-k-blu-ray-player;True;True;P-1900;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;164.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40025,7325578704;"61;2095";12;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000343-panasonic-dmp-bd60eg-k-blu-ray-player.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"LG W2261VP 54,6 cm (21,5 Zoll) Widescreen TFT Monitor HDMI/ DVI-D/ VGA ";"LG W2261VP 54,6 cm (21,5 Zoll) Widescreen TFT Monitor HDMI/ DVI-D/ VGA (Kontrastverhältnis 50000:1, Reaktionszeit 2ms) schwarz ";"
LG Electronics präsentiert: TFT Monitor FLATRON W2261VP
Multimedia Monitor mit erstklassigen Werten
Dank HDMI bietet dieser 22 Zoll LG Monitor vielfältige und zukunftssichere Anschlussmöglichkeiten. Mit seinem natürlichen 16:9 Blickfeld-Format eignet er sich perfekt für Gamer und Multimedia-Fans – nicht zuletzt auch aufgrund der schnellen Reaktionszeit von 2ms und dem hohen Kontrast von 50.000:1. Genießen Sie mit den innovativen Fun-Funktionen absoluten Bedienkomfort, dank Full HD und f-Engine perfekte Bildqualität und ein wertiges, edles Design in einem!
 
Beschreibung der Features
 
Perfektion in Full HD
Höchste Präzision und beste Qualität in der Darstellung sind in allen Bereichen – ob für Filme, Computerspiele, Multimedia- und Of?ce-Anwendungen – garantiert. Pixel für Pixel stellt dieser LG Monitor in einer Auflösung von 1920x1080 die Bilder unskaliert genauso dar, wie sie die Quelle liefert. Das sorgt für eine reibungslose Wiedergabe und garantiert extrem scharfe und kristallklare Bilder, die selbst bei Action-Szenen oder Sportübertragungen nicht ins Ruckeln geraten.
 
Hochgenuss im 16:9 Breitbildformat
Der W2261VP LG Monitor mit integriertem 16:9 Panel bringt überragende Bildqualität mit Full HD-Au?ösung im Breitbildformat zu Ihnen nach Hause. Das 16:9 Panel ist ein natürliches Blickfeld-Format, das Ihre Augen nicht übermäßig beansprucht. So können Sie Ihren Monitor sowohl für actiongeladene BluRay- oder DVD-Filme, zum digitalen Fernsehen oder für professionelle Aufgaben am PC ideal nutzen. Super bequem beim Arbeiten: Es lassen sich problemlos zwei DIN-A4-Hochformate nebeneinander anzeigen.
 
Scharfer Kontrast
Der ultra hohe Kontrast von 50.000:1 mit DFC (Digital Fine Contrast) bringt tiefstes Schwarz und strahlend helles Weiß auf Ihren Bildschirm. Farben zeigen sich brillant und lebensecht, so dass das Filmerlebnis am PC eine neue Dimension erreicht.
 
Schnelle Reaktionszeit
Durch die enorm schnelle Reaktionszeit der Hintergrundbeleuchtung von nur 2 Millisekunden werden Bewegungsunschärfen eliminiert und ein ruckelfreies Bilderlebnis garantiert. Bei Action?lmen, Sportübertragen oder Videogames verpassen Sie nun nichts mehr! Und dank des angenehm großen Blickwinkels von 170° kommen auch die richtig anspruchsvollen Multimedia- und Office-Anwender voll auf ihre Kosten.
 
Connected: HDMI
HDMI steht für ""High Definition Multimedia Interface"". Hierbei handelt es sich um eine zukunftssichere Schnittstelle für die volldigitale Übertragung von Audio- und Video-Daten in der Unterhaltungselektronik. Dieser Anschluss verbindet portable HDMI-Abspielgeräte mit Ihrem Display und ermöglicht eine verlustfreie High-Definition Bild- und Tonübertragung wobei eine Bildtiefe von bis zu 48-bit erreicht werden kann. Beim W2261VP Monitor haben Sie diesen komfortabel nutzbaren HDMI- sowie einen DVI-D Eingang mit HDCP Kopierschutzunterstützung.
 
Innovative FUN-Funktionen
Nutzen Sie praktische Photoeffekte für Farbkorrekturen in Bildern und Filmen oder die ez-Zooming-Funktion zur hochauflösenden Ausschnittvergrößerung von Bild und Text. Die 4:3 Formatumschaltung sorgt zudem für verzerrungsfreien Film- und Spielgenuss.
 
Alle Daten im Überblick
 
22"" TFT Monitor für den anspruchsvollen Multimedia Anwender im 16:9 Breitbildformat.
Funktionelles edles Design in hochglänzendem Schwarz
Ultra schnelles Panel mit kurzer Reaktionszeit von nur 2 ms (ISO) und sehr großem Blickwinkel von 170°; ideal für Multimedia-Anwender oder Gamer.
Ultra hoher Kontrast von 50.000:1 mit DFC (Digital Fine Contrast)
Full HD Auflösung (1920 x 1080 Pixel). Formatfüllende Darstellung von zwei DIN-A4 Seiten gleichzeitig.
f-Engine – LG's welterster Bildverbesserer Chip garantiert kristallklare und brillante Bilder ohne Farbverfälschung in Echtzeit für Film, Foto oder Anwender.
Neue ergonomische Menüführung mit Visual OSD
Fun Taste für Photoeffekte zur kreativen Darstellung von Bildern wie z.B. Sepia, kalt, und Gaussche Unschärfe. ez Zooming zur Änderung der Auflösung, oder ARC Formatumschaltung von 4:3 auf 16:9 zur formatgetreuen Darstellung von älteren Programmen.
HD fähig und zukunftssicher HDMI Eingang (bis 1080p) und DVI-D Eingang mit HDCP Kopierschutzunterstützung. Zusätzlicher VGA 15 Pin D-Sub Eingang zum Betrieb an zwei Rechnern.
Integriertes Netzteil
Kopfhörerausgang
Externes Netzteil 
";2;False;0;;;"LG W2261VP 54,6 cm (21,5 Zoll) Widescreen TFT Monitor HDMI/ DVI-D/ VGA ";lg-w2261vp-546-cm-215-zoll-widescreen-tft-monitor-hdmi-dvi-d-vga;True;True;P-2520;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;239.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40025,6372800926;"11;2095";19;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000337-lg-w2261vp-546-cm-215-zoll-widescreen-tft-monitor-hdmi-dvi-d-vga.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000338-lg-w2261vp-546-cm-215-zoll-widescreen-tft-monitor-hdmi-dvi-d-vga.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000339-lg-w2261vp-546-cm-215-zoll-widescreen-tft-monitor-hdmi-dvi-d-vga.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Western Digital My Passport Essential 500 GB ";"Western Digital BAAA5000ABK My Passport Essential 500GB ";"
Western Digital BAAA5000ABK My Passport Essential 500GB 
 
Unsere kleinste tragbare Festplatte aller Zeiten
Ihre gesamten Daten auf einen Blick und mühelose Widerhergestellung Ihrer Daten
Passwortschutz und 256-bit Hardware basierte Verschlüsselung
Plug-and-play-bereit für Windows-PCs
Lieferumfang: Western Digital My Passport Essential 500GB externe Festplatte,
SmartWare-Software, USB-Kabel, Schnellinstallationsanleitung
";2;False;0;;;Western Digital My Passport Ess. 500GB schwarz;western-digital-my-passport-essential-500-gb;True;True;P-2570;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;109.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40015,1174768519;14;21;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000336-western-digital-my-passport-essential-500-gb.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;LG BD 370 Blu-ray Disc Player schwarz;"LG BD 370 Blu-ray Disc Player schwarz ";"

LG BD 370 Blu-ray Disc Player schwarz 

HDMI, Upscaler 1080p, BD live, You Tube-Video Client, Ethernet, USB 2.0

Der neue BD-370 verbindet wie kein anderer Blu-ray Player das Internet mit dem Fernsehen.
Über eine LAN-Verbindung können Sie YouTube Video-Streams wiedergeben.
Die BD-Live Funktion versorgt Sie über das Internet mit Zusatzinformationen zu den Filmen,
wie z.B. Kommentare oder Extra-Material. Wie von LG gewohnt, liefert der BD-370 perfekte Bildqualität
und ist, kombiniert mit einem FullHD TV, unschlagbar in Sachen Bildqualität.
 
Blu-ray Disc Player zur Wiedergabe von: Blu-ray Discs, BD-R(E), Video DVDs (PAL & NTSC), DVD+R(W), DVD-Dual Layer,
DVD+R Double Layer, Audio-CD, DTS-CD, MP3 CD, WMA CD, PNG, CD, DivX CD, JPEG CD, CD-R(W)
Unterstützung interaktiver Blu-ray Disc Standard-Inhalte & BD Live 2.0
YouTube™ Video-Streaming Wiedergabe über LAN
USB 2.0 und HDMI 1.3 1080p Ausgang mit SIMPLINK & Deep Colour,
A/V-Ausgang (Cinch), Komponentenausgang YUV, RJ45 LAN-Anschluß
Dolby TrueHD, Dolby Digital, Dolby Digital Plus, DTS-HD, DTS, LPCM, MP3, WMA, MPEG1/2 L2
";2;False;0;;;LG BD 370 Blu-ray Disc Player schwarz;lg-bd-370-blu-ray-disc-player-schwarz;True;True;P-1890;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;147.9000;147.9000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40013,6568865741;61;19;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000333-lg-bd-370-blu-ray-disc-player-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000334-lg-bd-370-blu-ray-disc-player-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000335-lg-bd-370-blu-ray-disc-player-schwarz.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Samsung DVD-HR 775 A DVD-/Festplatten-Rekorder ";"Samsung DVD-HR 775 A DVD-/Festplatten-Rekorder 250 GB ";"
Multiformat DVD-Recorder im 55 Millimeter Slim Design mit 250 GB HDD,
 
USB 2.0, MPEG4 (DivX), HDMI™-Ausgang (1.080p/ 1.080i / 720p),
 
Anynet+ (HDMI-CEC), TimeShift, TimeSlip und ShowView.
 
 
Aufnahme auf Festplatte
Die eingebaute Festplatte mit 320 / 250 / 160 GB im DVD-HDD-Recorder macht‘s möglich: Im EP-Modus können Sie bis zu 534 / 421 / 264 Stunden Filme aufzeichnen.
 
One-Touch-Aufnahme
Die Samsung DVD-Recorder machen das Aufzeichnen leichter denn je. Ein Knopfdruck genügt – schon sucht der Samsung Recorder nach dem verfügbaren Aufnahmeplatz auf der Disc und beginnt mit der Aufnahme. Einmal drücken bedeutet Aufnahme bis zu 30 Minuten, zweimal drücken bis zu einer Stunde. Mit jedem Tastendruck zeichnet der Samsung DVD-Recorder weitere 30 Minuten des ausgewählten Programms auf. Die Aufnahmezeit auf einer Disc beträgt je nach Aufnahmemodus maximal 240 Minuten.
 
Automatische Fehlerkorrektur
Die Bildqualität der auf DVD gespeicherten Daten kann bei einer verbogenen Disc verzerren. Der Grund: Diese Disc lässt sich aufgrund der Unregelmäßigkeit der Laserreflexion nicht korrekt lesen. Zur Verbesserung der Lesbarkeit sind Samsung Recorder mit einer automatischen Fehlerkorrektur-Technologie ausgestattet. Diese Technik verbessert die Datenleserlichkeit selbst bei Discs, die Unregelmäßigkeiten aufweisen.  VBR-Technologie
Mit der VBR (Variable Bit Rate)-Technologie kann die Aufnahmezeit durch Einstellen des Aufnahmemodus auf bis zu 16 Stunden verlängert werden. Um Bilder auf DVD-RW und DVD-R aufzuzeichnen, steuert die VBR-Kodiertechnik die Komprimierungsrate von MPEG2 in Echtzeit und maximiert dadurch den verfügbaren Speicherplatz auf der Disc.
 
Was bedeutet White Strategy?
Bei der ""Präzise Aufzeichnung und Wiedergabe""-Technologie passen sich die gespeicherten Daten sauber in den optimalen Bereich an. Die Daten, die ohne diese Technik gespeichert werden, viel mehr Platz ein, was zu einer Datenüberlappung führen kann. Dank der ""Präzisen Aufzeichnung und Wiedergabe"" werden die Daten im Samsung DVD-Recorder noch präziser gespeichert. So entstehen kristallklare Bilder.
 
Was ist HDMI™?
HDMI™ (kurz für High-Definition Multimedia Interface) ist eine volldigitale Audio/Video-Schnittstelle, die Bild- und Tondaten mit einem einzigen Digitalkabel zwischen Digital- und Audiogeräten überträgt. Es unterstützt die Videoformate Standard, Enhanced oder High-Definition sowie die Audioformate Standard bis mehrkanaligen Surround-Sound. Die Vorteile: unkomprimierte digitale Videodaten (mit Bandbreiten bis zu 5 Gigabyte pro Sekunde), ein Anschluss statt vieler Kabel und Datenaustausch zwischen Bildquelle und DTV. 
";2;False;0;;;;samsung-dvd-hr-775-a-dvd-festplatten-rekorder;True;True;P-1940;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;269.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40013,6237847222;63;5;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000331-samsung-dvd-hr-775-a-dvd-festplatten-rekorder.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000332-samsung-dvd-hr-775-a-dvd-festplatten-rekorder.jpg;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Canon Digital IXUS 95 IS Digitalkamera Silver;"Canon Digital IXUS 95 IS Digitalkamera Silver ";"
Canon Digital IXUS 95 IS Digitalkamera Silver

10 Megapixel, 3-fach opt. Zoom, 2,5"" Display, Bildstabilisator
 
Die Digital IXUS 95 IS vereint exquisiten Schick mit exzellenter Leistung und hohem Komfort.
Der innovative Smart-Auto-Modus nutzt auf intelligente Art die Scene-Detection-Technologie.
Das Ergebnis: optimierte Einstellungen für tolle Bilder. Kompaktes und schickes IXUS-Design mit 10 Megapixeln in 3,0fach optisches Zoom

mit optischem Bildstabilisator Scene-Detection-Technologie Brillante Aufnahmen Face-Detection-Technologie DIGIC 4 2,5-Zoll-PureColor-LCD II i-Contrast 17 Aufnahmemodi VGA-Movieclips
Technische Daten der Canon Ixus 95 IS : Auflösung (MP) 10 Sensor-Größe 1/2.3 LCD-Größe (cm) 6.35 Speicher SD / SDHC interner Speicher (MB)

optischer Zoom (x-fach) 3 numerischer Zoom (x-fach) 4 Bildstabilisator Ja Optischer Zoom Nein Brennweite 35 - 105 Lichtstärke 2.8 - 4.9 Video-Modus JA

Max. Video-Auflösung(Pixel) 640 x 480 Abmessungen (B x H x T mm) 88,5 x 54,8 x 21,8 Gewicht (g) 120 Akku NB-6L
 
Lieferumfang:
Digital IXUS 95 IS, Trageriemen, Akku, Akku-Ladegerät, USB-Kabel, Video-Kabel
";2;False;0;;;"Canon Digital IXUS 95 IS Digitalkamera ";canon-digital-ixus-95-is-digitalkamera-silver;True;True;P-1700;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;189.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40008,648287037;56;25;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000324-canon-digital-ixus-95-is-digitalkamera-silver.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000325-canon-digital-ixus-95-is-digitalkamera-silver.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000326-canon-digital-ixus-95-is-digitalkamera-silver.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Garmin TOPO DVD Deutschland Digital 25 ";"Garmin TOPO DVD Deutschland Digital 25 ";"
Garmin TOPO DVD Deutschland Digital 25 

 
Topographische Rasterkarte von Deutschland im Maßstab von 1:25.000
 
 
Topographische Rasterkarte
Maßstab 1:25.000
3D-Geländedarstellung mit Flugmodus
Erstellen von Höhenprofilen
Übertragen von Routen, Tracks und Wegpunkten
";2;False;0;;;;garmin-topo-dvd-deutschland-digital-25;True;True;P-2050;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;159.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40007,1684027778;67;44;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000323-garmin-topo-dvd-deutschland-digital-25.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Garmin Topo DVD Deutschland V3;"Garmin Topo DVD Deutschland V3 Gesamt Digitale topographische Karte gesamt Deutschland auf DVD und MircoSD-Karte ";"

Garmin Topo DVD Deutschland V3 Gesamt

 
Digitale topographische Karte gesamt Deutschland auf DVD und MircoSD-Karte
 
.
Die neue topographische Karte gesamt Deutschland
enthält zusätzlich zu detaillierten Straßen- und Wegedaten mehr als 8.000 km überregionale Wanderrouten und über 60.000 km Radrouten.
Innerhalb dieses Routennetzes kann sich der Nutzer von einem bestimmten Ausgangspunkt zu einem Zielpunkt routen lassen.
Beispiele für Routen: Rothaarsteig, Rennsteig, Altmühltal-Panoramaweg, Harzer Hexensteig, 66 Seen Wanderweg, Premiumwanderwege Saarland und viele mehr.
Neu ist auch, dass die Kartensoftware erstmals kompatibel mit Apple MacIntosh Computern ist (ab OS X 10.4 aufwärts).
Ob zu Fuß oder auf dem Mountain-Bike,
wer viel draußen unterwegs ist, setzte früher Papierkarten ein. Seit mehreren Jahren gibt es von Navigationsspezialist Garmin GPS-Geräte
die topografische Karten darstellen können (Karten im MapSource-Format). Ein Routing, wie man es von Navis aus dem Auto kennt, war mit diesen Karten bislang aber nicht möglich.
Die neueste Version der “Topo Deutschland v3” macht nun erstmals das Routing auf 8.000 km Wanderrouten und rund 60.000 km Radrouten möglich!
Einfach Start- und Zielpunkt eingeben, das Gerät schlägt die Route vor, und los geht’s. Visuelle Abbiegehinweise führen dann bequem und sicher zum Ziel.
Dies sollte auch den größten GPS-Skeptiker positiv stimmen.
Ebenfalls praktisch:
Die neue Topo Deutschland V3 wird mit einer bereits programmierten SD-/microSD Datenkarte ausgeliefert.
Das erspart ein Freischalten der Karte auf dem PC und das Übertragen der Karte auf das Gerät.
Die Datenkarte wird einfach in den Slot des GPS-Gerätes geschoben und schon kann es losgehen.
Eine Verwendung der Daten von der DVD auf dem Computer ist natürlich nach wie vor möglich.

";2;False;0;;;Garmin Topo DVD Deutschland V3;garmin-topo-dvd-deutschland-v3;True;True;P-2040;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;209.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;40007,1559606481;67;44;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000322-garmin-topo-dvd-deutschland-v3.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"NAVIGON 2310 Navigationssystem Europa ";"NAVIGON 2310 Navigationssystem Europa ";"

NAVIGON 2310 Navigationssystem Europa

 
40 Länder, inklusive TMC, NAVIGON MyRoutes, Clever Parking , TMC-Routenplanung
 
 
NAVIGON 2310 Kann noch mehr,als das Äußere verspricht.
Was macht eigentlich ein Schmuckstück aus? Erstmal muss es natürlich gut aussehen.
Im ersten Moment könnte man die 23er-Serie von NAVIGON für so ein typisches, kleines Accessoire halten.
Aber nicht nur das schicke Design begeistert. Denn auch was die Features angeht, kann die 23er-Serie locker mithalten:
Mit TMC- Routeninfo stehen Sie nie wieder im Stau, NAVIGON MyRoutes findet jederzeit die für Sie beste Strecke und mit dem POI-Klick erhalten Sie alle Infos zu Ihrem gewählten Sonderziel.
Und wenn Sie das immer noch nicht überzeugt, dann sehen Sie sich mal den Preis an.
 
NAVIGON MyRoutes
Je nachdem, welcher Fahrertyp Sie sind, empfiehlt Ihnen NAVIGON MyRoutes die beste Route – zugeschnitten auf Ihren persönlichen Fahrstil, den Wochentag und die Tageszeit.
Darüber hinaus zeigt Ihnen Ihr NAVIGON bis zu zwei weitere Routen. Das schafft Transparenz. Sie entscheiden, ob Sie unserer Empfehlung folgen oder eine der Alternativen wählen.
 
TMC-Routeninfo
zeigt ihnen im Fall einer Staumeldung eine Alternativroute mit aktualisierter Entfernung und Ankunftszeit. Sie entscheiden, ob eine Umfahrung in Ihrem Fall sinnvoll ist oder ob Sie die ursprüngliche Route beibehalten wollen.
 
Reality View Pro
zeigt Straßen nicht als Linien, sondern realistisch aus Asphalt und mit Mittelstreifen. So behalten Sie an Autobahnkreuzen und Ausfahrten leichter den Überblick.
 
Fahrspurassistent Pro
hilft Ihnen selbst durch den hektischsten Straßenverkehr hindurch. Vorausschauend und übersichtlich zeigt er Ihnen an, auf welche Fahrspur Sie für Ihren nächsten und übernächsten Abbiegepunkt wechseln müssen.
 
Clever Parking
hilft Ihnen bei der Parkplatzsuche. Kurz vor Ihrem Ziel zeigt Ihnen Clever Parking Parkplätze in der näheren Umgebung an.
In Deutschland werden Sie sogar über Parkgebühren informiert. So vermeiden Sie langes Suchen und sparen dabei Geld.
 
Lieferumfang:
PNA  2310 (3,5"" im 4:3 Format) | Kurzanleitung | Kfz-Ladekabel mit integrierter TMC-Antenne | Halterung | Vorinstalliertes Kartenmaterial für 40 Länder | USB-Kabel
";2;False;0;;;;navigon-2310-navigationssystem-europa;True;True;P-2150;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;159.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39998,914525463;68;14;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000321-navigon-2310-navigationssystem-europa.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Panasonic Lumix DMC-FS6 Digitalkamera schwarz;"Panasonic Lumix DMC-FS6 Digitalkamera schwarz ";"

Panasonic Lumix DMC-FS6 Digitalkamera schwarz

 
8 Megapixel, 4-fach opt. Zoom, 2,5"" Display, Bildstabilisator
 
 
Im Intelligenten Automatik (iA)-Modus werden die 5 wichtigsten Motivprogramme automatisch optimal auf die jeweilige Szene eingestellt.
Neben der Motiverkennung kombiniert iA weitere wichtige Funktionen, wie den optischen Bildstabilisator OIS, die Bewegungserkennung (Intelligente ISO-Steuerung),
eine optimierte Gesichtserkennung mit digitaler Rotaugen-Korrektur.
So sind scharfe, natürliche und schöne Fotos selbst für (Neu-)Einsteiger möglich.
Der reaktionsschnelle Venus Engine IV-Bildprozessor gehört schon bei diesem Einsteigermodell zur Grundausstattung.

Lichtstarkes F2,8 Leica DC Vario-Elmarit Objektiv
Hochauflösendes 6,4 cm LC-Display [230.000 Pixel]
4x optischer Zoom [KB: 33-132 mm]
Intelligente Automatik [u.a. Gesichtserkennung]
 
Lieferumfang:
Digitalkamera, Lithium Ionen Akku, Ladegerät, USB-Kabel, Trageriemen, Audio / Video-Kabel, CD-ROM, Sotware
";2;False;0;;;"Panasonic Lumix DMC-FS6 ";panasonic-lumix-dmc-fs6-digitalkamera-schwarz;True;True;P-1770;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;189.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39998,8940393519;58;12;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000317-panasonic-lumix-dmc-fs6-digitalkamera-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000318-panasonic-lumix-dmc-fs6-digitalkamera-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000319-panasonic-lumix-dmc-fs6-digitalkamera-schwarz.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Western Digital WD TV HD Media Player;Western Digital WD TV HD Media Player;"
Western Digital WD TV HD Media Player
 
 
In Kombination mit einem tragbaren My Passport-Laufwerk ist dieser Player die bequemste Methode, Filme oder selbstgedrehte Videos wiederzugeben,
digitale Musik in hoher Qualität abzuspielen und Diashows Ihrer Familienfotos in hoher Auslösung von der Festplatte in Ihrem Fernseher anzuzeigen.
Auch mit gängigen USB-Laufwerken und Digitalkameras, Camcordern und tragbaren Media-Playern, die als Massenspeichereinheiten erkannt werden, kompatibel.
Ideal geeignet für eine störungsfreie Wiedergabe von Filmen, Heimvideos, digitaler Musik und Fotos von der Festplatte auf Ihrem Fernsehgerät.
 
HDMI- und FBAS-Anschlüsse - Der HDMI-Anschluss (HDMI – High-Definition Multimedia Interface) ermöglicht den Anschluss an HDTV-Geräte der höchsten Qualität oder an ein Heimtheater.
Zusätzliche kombinierte (RCA-)Ausgänge gewährleisten die Kompatibilität mit praktisch allen Fernsehgeräten.
 
Highlights
maximale Transferrate: 480 Mb/s über USB 2.0
USB 2.0 Anschluss
für PC oder Macintosh Computer
Lieferumfang: HD Media Player, kompakte Fernbedienung einschließlich Batterien,
Software für Medienkonvertierung (nur für Windows), kombiniertes Audio/Video-Kabel, Netzteil, Schnellinstallationsanleitung
";2;False;0;;;Western Digital WD TV;western-digital-wd-tv-hd-media-player;True;True;P-2560;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;119.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39997,7782638889;14;21;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000316-western-digital-wd-tv-hd-media-player.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"TomTom 220V Netzteil ";"TomTom 220V Netzteil ";
220V Netzteil TomTom Navigation

Ladegerät mit abgewinkeltem 90° Spezialstecker

Steckerlader für Tom Tom Serien: ONE XL Europe HD Traffic Regional,
Go Serien 520 Go 720 Go 740 Go 920 Live XL XL LIVE IQ Routes
Netzteil Ladegerät 240 Volt Output: 5.5V +/- 5%
Mit Ladekontrollleuchte (LED), nur 85 Gramm
Hochflexibeles, kerbfestes Kabel, beste Qualität
Auslieferung in Kartonbox und Schutzumschlag
CE, beste Qualität original von Spartechnik
;2;False;0;;;"Reiseladegeraet / Netzteil / Ladegeraet fuer TomTom ";tomtom-220v-netzteil;True;True;P-1970;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;14.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39986,6084953704;66;4;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000311-tomtom-220v-netzteil.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Tom Tom One Hard Case XL schwarz ";"Tom Tom One Hard Case XL schwarz ";"

Tom Tom One Hard Case XL schwarz
 
 

Hard Case Tom Tom One XL, Schwarz
passgenaue, stoßfeste Tasche aus Nylon/EVA
Farbe: Schwarz
Ausstattung:
mit zusätzlichem Staufach für Zubehör
Handschlaufe für einfachen Tragekomfort
";2;False;0;;;"Tom Tom One Hard Case XL schwarz ";tom-tom-one-hard-case-xl-schwarz;True;True;P-1960;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;20.9900;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39986,6020023148;66;4;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000265-tom-tom-one-hard-case-xl-schwarz.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"TomTom XL IQ RoutesTM-Edition Europe ";"TomTom XL IQ RoutesTM-Edition Europe mit TMC ";"

TomTom XL IQ RoutesTM-Edition Europe mit TMC
 

42 Länderkarten, Fahrspurassistent, Text-to-Speech, Intelligente Routenberechnung,TMC
 

TomTom Navigationsgerät XL IQ Routes Edition Europe 42 Traffic mit 4,3 Zoll Farb-Touchscreen, RDS/TMC,
42 vorinstallierten Karten europäischer Länder sowie vielen Innovationen für eine verbesserte und komfortable Navigation IQ Routes -
Intelligente Routenberechnung aus aktuellsten Karten unter Berücksichtigung verschiedener Umweltfaktoren wie Tag, Uhrzeit,
 
Straßenabschnitt, Durchschnittsgeschwindigkeiten etc.
Fahrspurassistent für komplizierte Spurenführung, zwei Ausfahrten in einer Ansicht und verbesserte Gebietsabdeckung Text-to-Speech zum Ansagen von Straßennamen und Verkehrshinweisen für einen konzentrierten Blick auf die Fahrbahn und ein entspanntes Fahren
 
Lieferumfang:
XL IQ Routes Edition Europe 42 Traffic, EasyPort-Halterung, USB-Kabel, Autoladegerät, Dokumentation, RDS/TMC-Verkehrsinfo-Empfänger
 
";2;False;0;;;"TomTom XL IQ RoutesTM-Edition Europe ";tomtom-xl-iq-routestm-edition-europe;True;True;P-1950;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;164.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39986,5911689815;66;4;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000264-tomtom-xl-iq-routestm-edition-europe.jpg;;;1;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Trekstor DataStation maxi g.u 500 GB ";"Trekstor DataStation maxi g.u 500 GB USB 2.0 ";"

Trekstor DataStation maxi g.u Externe Festplatte 500 GB USB 2.0

 
 
 
Optimale Speicherplatzerweiterung
Die DataStation maxi g.u ist die perfekte Lösung für das tägliche Backup oder die Speicherplatzerweiterung Ihres PCs.
Die externe 3,5“ Festplatte bietet ausreichend Platz zum Speichern und Archivieren der heimischen
Musik- und Videosammlung, digitaler Fotos oder anderer Dateien.
Schnell und bedienungsfreundlich
Mit dem Hi-Speed USB 2.0 Anschluss bietet die DataStation maxi g.u einen schnellen Datentransfer.
Die Festplatte ist zudem bereits vorformatiert und ohne Treiber sofort betriebsbereit.
Unterstützt werden alle gängigen Dateisysteme von Windows®, Linux® und Mac® OS X, sowie die Betriebssysteme Microsoft Windows® 2000 / XP/ Vista,
Mac® OS X ab 10.3 und Linux® ab Kernel 2.6.x. Die Festplatte wird über das mitgelieferte Netzteil mit Strom versorgt.
Der Ein-/Ausschalter am Festplattengehäuse verhindert überflüssigen Stromverbrauch.
Inklusive Nero Software „BackItUp2 Essentials“
Die ebenfalls im Lieferumfang enthaltene Nero Software rundet das Bild der mobilen, externen Festplatte perfekt ab.
Mit Nero BackItUp2 Essentials können Sie Backups Ihrer Daten sehr einfach planen.
So können einzelne Dateien oder ganze Laufwerke gesichert werden.
Um die Datenmenge gering zu halten, komprimiert die Software die Backups direkt „on the fly“.
Auf Wunsch lassen sich die gesicherten Daten auch per Passwortschutz vor unbefugtem Zugriff schützen.
 
Lieferumfang: Externes Festplattenlaufwerk, USB 2.0-Kabel, Netzteil, Schnellinstallationsanleitung
";2;False;0;;;Trekstor DataStation maxi g.u;trekstor-datastation-maxi-gu-500-gb;True;True;P-2650;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;99.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39982,6066203704;15;2;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000129-trekstor-datastation-maxi-gu-1tb.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Canon Digital IXUS 100 IS Digitalkamera schwarz;"Canon Digital IXUS 100 IS Digitalkamera schwarz ";"

Canon Digital IXUS 100 IS Digitalkamera schwarz

12 Megapixel, 3-fach opt. Zoom, 2,5""Display, HDMI, SLIM
 
Die Digital Ixus 100 IS präsentiert sich im atemberaubend-exquisiten, nur 18,4 Millimeter flachen Edelstahlgehäuse. Sie ist in den vier Farben Silber, Schwarz, Gold und Rot erhältlich.
 
Ob großformatige Fotoprints oder gezielte Ausschnittvergrößerungen: Die hohe Auflösung von 12,1 Megapixeln sorgt für eine überzeugende Detailwiedergabe.
 
Für hohe Geschwindigkeit und exzellente Bildqualität mit brillanten Farben und minimiertem Bildrauschen steht der aktuelle Canon-Bildprozessor DIGIC 4.
12,1 Megapixel Sensor
3-fach optisches Zoom
Großes hochauflösendes 2,5 Zoll PureColor LCD II
Superschlank; HD-Movie und HDMI-Anschluß  mehr Details im Film
 
Lieferumfang:
Digital IXUS 100 IS, Trageriemen, Akku, Akku-Ladegerät, USB-Kabel, Video-Kabel
";2;False;0;;;"Canon Digital IXUS 100 IS Digitalkamera ";canon-digital-ixus-100-is-digitalkamera-schwarz;True;True;P-1690;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;219.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39964,877037037;"56;2095";25;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000251-canon-digital-ixus-100-is-digitalkamera-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000252-canon-digital-ixus-100-is-digitalkamera-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000253-canon-digital-ixus-100-is-digitalkamera-schwarz.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Apple iPod Touch 32 GB schwarz;"Apple iPod Touch 32 GB schwarz mit integrierter WiFi Funktion ";"
Apple iPod Touch 32 GB schwarz mit integrierter WiFi Funktion

Der iPod touch kann alles, was du am iPod toll findest. Und noch vielmehr. Schlankes neues Design. Mit seinem fantastisch flachen Edelstahl-Design liegt der iPod touch mit dem 3.5 Zoll Touch-Display jetzt noch besser in der Hand. Mobil im Spiel. Durch revolutionäre Technologien wie das Multi-Touch-Display, der Beschleunigungssensor und 3D-Grafiken macht das Spielen auf dem iPod touch besonders viel Spaß. Schlaue Musik Mit der neuen Funktion ""Genius"" wird der iPod touch zu Deinem superintelligenten, persönlichen DJ.
 
Nur ein paar Fingertipps, und Genius erzeugt eine Wiedergabeliste mit Songs Deiner Mediathek, die gut zusammenpassen. Internet überall Internetzugang überall, wo ein drahtloses Netzwerk zur Verfügung steht, damit Sie immer mit dabei sind. Multitouch-Oberfläche: Die revolutionäre Technologie des iPhone und die Software Version 3.1 stecken in diesem genialen iPod. Das brillante Breitformat-Display rückt Ihre Videos und Spiele ins beste Licht und dank OpenGL sehen die Spiele jetzt noch besser aus Surfen Sie mit Safari im Web und sehen Sie YouTube Videos auf dem iPod mit integrierter Wi-Fi Funktionalität an. Mit Ihrem iPod touch können Sie im iTunes Wi-Fi Music Store nach Songs suchen, Hörproben abspielen und Titel kaufen.
 
Lieferumfang: iPod touch, Ohrhörer, USB 2.0 Kabel, Kurzanleitung
 
Schlankes neues Design
Mit seinem fantastisch flachen Edelstahl-Design liegt der iPod touch so gut in der Hand wie nie zuvor. Ebenfalls Eindruck machen der neue Lautstärkeregler und der integrierte Lautsprecher.
 
Spiele
Speziell auf die iPod touch Technologie zugeschnittene Spiele sind nur noch einen Fingertipp entfernt. Stöbere in hunderten von Spielen im App Store direkt auf Deinem iPod touch, und wenn Du gefunden hast, was Du suchst, kannst Du es einfach laden und dann kann es losgehen.
 
Steuerung per Fingertipp
Viele Spiele auf dem iPod touch nutzen die Multi-Touch-Technologie für besonders exakte Fingertipp-Steuerung der verschiedenen Spielelemente. Beim Schach ziehst Du mit dem Finger die Figuren, bei Würfelspielen bewegst Du die Würfel. Durch Ziehen mit zwei Fingern kannst Du die Anzeige vergrößern und verkleinern, Deine Figur nach links oder rechts drehen, und durch einfaches Antippen triffst Du eine Auswahl.
 
Musik
Blättere in den Albumcovern Deiner Musiksammlung. Erstelle immer wieder neue Genius Wiedergabelisten und erweitere Deine Sammlung aus dem iTunes Wi-Fi Music Store überall, wo ein Wi-Fi-Hotspot in der Nähe ist.
 
Mit Cover Flow lebt das Flair einer CD- oder Plattensammlung wieder auf. Wer erinnerst sich nicht an das Gefühl beim Durchblättern der Sammlung? Das gibt es jetzt auch auf dem iPod touch: einfach iPod drehen, durch die Cover blättern, ein Album auswählen, fertig. Ein Fingertipp aufs Cover, und schon siehst Du die Titelliste, ein weiterer Tipp spielt die Musik ab, und dabei kannst Du sogar die Songtexte anzeigen.
 
Ein Musikgenie
Stell Dir vor, Du hörst einen Song. Toll wären jetzt andere Titel, die gut dazu passen. Was machst du? Ganz einfach: Du verwendest die neue Funktion ""Genius"". Diese findet die Songs in Deiner Mediathek, die gut zusammenpassen. Du erhältst eine Genius Wiedergabeliste, die Du sofort anhören, sichern oder sogar aktualisieren kannst. Verlass Dich also auf den Genius von iTunes, wenn Du einen Mix willst, auf den Du selbst nicht gekommen wärst.
 
Lautsprecher integriert
Mit dem integrierten Lautsprecher kannst Du Musik und Gespräche ohne Kopfhörer hören – perfekt für zwangloses Hörvergnügen.

Längere Batterielaufzeit
Jetzt kannst Du noch länger rocken (und ansehen und spielen). Der iPod touch hält bis zu 36 Stunden bei Musik oder bis zu 6 Stunden bei Videos durch. Das reicht für drei oder vier Filme zwischen den Ladevorgängen.
 
Internet
Surfe im Internet mit Wi-Fi. Du kannst detailgenaue HTML-E-Mails mit Anlagen empfangen und Wegbeschreibungen und aktuelle Verkehrsinformationen abrufen. Auch als YouTube-Fan entgeht Dir nichts.
 
Überall ins Internet
Der iPod touch ist der einzige iPod mit kabellosem 802.11b/g Internetzugriff. Bei bestehender Wi-Fi-Verbindung kannst Du im Internet surfen und Nachrichten lesen, Sportergebnisse sehen, Rechnungen bezahlen und online einkaufen.
 
Wer suchet, der findet
Der iPod touch synchronisiert Deine Lesezeichen vom PC oder Mac, sodass Du ruck zuck auf Deine Lieblingsseiten zugreifen kannst. Die Google- und Yahoo!-Suche ist schon integriert, sodass Du im Web schnell findest, was Du suchst.
 
Zoom mit Aussicht
Jeden beliebigen Ausschnitt einer Webseite kannst Du vergrößern, indem Du mit dem Finger darauf tippst oder mit zwei Fingern die Anzeige aufziehst. Websites lassen sich im Hoch- oder Querformat anzeigen: einfach den iPod touch um 90 Grad drehen, und schon wird auch die Darstellung der Website gedreht.
 
Eigene Weblinks
Für häufig besuchte Websites, etwa die einer Zeitung, eines Blogs oder eine Sport-Website, kannst Du einfach ein Symbol auf dem Home-Bildschirm erstellen. Deine Lieblingsseiten sind über mit Safari erstellte Weblinks nur einen Fingertipp entfernt.
 
Rock 'n' Run mit Nike+
Im iPod touch ist kabellose Unterstützung für Nike + iPod integriert. Du brauchst nur einen Nike + iPod Sensor in Deinem Schuh, und schon kann's losgehen.
 
Das optimale Lauftraining
Im iPod touch ist jetzt Unterstützung für Nike + iPod integriert. Einfach den Nike + iPod Sensor (separat erhältlich) in den Nike+ Laufschuh einsetzen, und es kann losgehen. Der Sensor überträgt die Laufdaten drahtlos an den iPod touch – er erfasst die gelaufene Zeit, die zurückgelegte Strecke und die verbrauchten Kalorien. Außerdem gibt er Dir gesprochenes Feedback zu Deinen Trainingsfortschritten.
 
Das optimale Fitnesstraining
Diese Funktion kann auch zusammen mit neuen, in vielen Fitnessstudios vorhandenen Geräten für das Ausdauertraining gekoppelt werden. Suche einfach nach mit Nike + iPod kompatiblen Laufbändern, Elliptical Trainern, Steppern und Hometrainern.
";2;False;0;;;Apple iPod Touch 32 GB;apple-ipod-touch-32-gb-schwarz;True;True;P-1260;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;277.9000;277.9000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39915,3405439815;43;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000141-apple-ipod-touch-16-gb-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000142-apple-ipod-touch-16-gb-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000143-apple-ipod-touch-16-gb-schwarz.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Apple iPod shuffle 4 GB silber;Apple iPod shuffle 4GB silber;"
Apple iPod shuffle 4GB silber
 
 
Der kleinste iPod der Welt
 
 
Um den kleinsten iPod der Welt zu bauen, haben wir die Steuerung vom iPod shuffle in das Ohrhörerkabel integriert.
So wird der iPod shuffle noch kleiner und die Steuerung ist genau da, wo du sie einfach erreichst.
Wenn du einen Song abspielen, anhalten oder überspringen möchtest,
musst du nicht lange nach dem iPod shuffle suchen - greif einfach zum Kabel und drücke auf eine der Tasten.
Dieser Entertainment-Winzling sagt Ihnen auf Knopfdruck, welchen Titel er gerade abspielt
Organisieren Sie Ihre Musik in verschiedenen Wiedergabeslisten
Dank eines stabilen, integrierten Clips lässt sich der iPod shuffle fast überall befestigen.
Lassen Sie sich aufs Ungewisse ein: Verwenden Sie den Schalter für die Zufallswiedergabe,
um den Inhalt Ihres iPod shuffle neu zu mischen.
Lieferumfang: Apple Earphones mit Remote Fernbedienung
 
iPod shuffle - In leuchtenden neuen Farben spricht Musik dich richtig an
 
Der kleinste iPod der Welt
Um den kleinsten iPod der Welt zu bauen, haben wir die Steuerung vom iPod shuffle in das Ohrhörerkabel integriert. So wird der iPod shuffle noch kleiner und die Steuerung ist genau da, wo du sie einfach erreichst. Wenn du einen Song abspielen, anhalten oder überspringen möchtest, musst du nicht lange nach dem iPod shuffle suchen - greif einfach zum Kabel und drücke auf eine der Tasten.
 
Der erste iPod, der mit dir spricht
Die VoiceOver Funktion ist mit Sicherheit der nächste Hit auf dem iPod shuffle.1 Angenommen du hörst einen Song und willst wissen, wie er heißt oder von wem er ist: Einfach Knopf drücken und VoiceOver sagt es dir. Sogar die Namen deiner Wiedergabelisten verrät es dir. Und wenn die Batterie aufgeladen werden muss, sagt VoiceOver dir das auch.
 
Leichtbedienung
Die Steuerung befindet sich am Kabel des rechten Ohrstöpsels. Dadurch, dass die Steuerung jetzt hier angebracht ist, kannst du deine Musiktitel durchsuchen - und die VoiceOver Funktion aktivieren - ohne vom Joggen, Rad fahren oder anderen Aktivitäten abgelenkt zu werden. Der iPod shuffle wird mit dieser einfachen Steuerung geliefert. Du kannst aber auch Kopfhörer mit ähnlichen Bedienelementen von Herstellern wie Scosche, Klipsch, V-MODA und Belkin verwenden.
 

Dein Musikarchiv. Für unterwegs
Der iPod shuffle kommt jetzt mit 2 GB oder 4 GB. Mit dem 4 GB Modell hast du jede Menge Platz, um Musik für viele Stunden - bis zu 1.000 Songs - zu speichern.2 Damit bist du im Fitnessstudio oder auf dem Weg zur Arbeit bestens gerüstet. Außerdem kannst du jetzt mehrere Wiedergabelisten und auch Hörbücher verwenden.
 
Mehrere Wiedergabelisten
Wahrscheinlich hast du dir in iTunes schon einige Wiedergabelisten zusammengestellt. Eine für unterwegs. Eine fürs Fitnessstudio. Eine zum Chillen. Jetzt kannst du deine Wiedergabelisten auf dem Computer mit dem iPod shuffle synchronisieren und hast immer genau den richtigen Mix - egal, was du gerade machst oder in welcher Stimmung du bist. VoiceOver nennt dir den Namen jeder Wiedergabeliste. So kannst du ganz leicht zwischen ihnen wechseln und genau die auswählen, nach der dir gerade ist.
 
Farbe bekennen
Mit dem flachen, robusten Gehäuse aus eloxiertem Aluminium ist der iPod shuffle immer das passende Accessoire. In leuchtendem Pink, Blau, Grün, Schwarz oder Silber ist er ein echtes Fashion Statement. Ganz neu dabei: der iPod shuffle Special Edition in poliertem Edelstahl (So werden Rockstars nun mal behandelt). Sogar der iPod shuffle Clip sieht stylish aus. Er klemmt sicher an Hemd, Jacke, Sportzeug oder am Rucksack. So wird der iPod shuffle zum perfekten Fashtech-Accessoire. Und klar, natürlich ist noch Platz für eine persönliche Gravur.

Mehrsprachig
Ein französisches Chanson. Ein spanischer Bolero. Eine italienische Arie. Dein Musikarchiv enthält Musik aus allen Ländern der Welt. Deshalb spricht VoiceOver 20 Sprachen und kann die Namen von Songs und Interpreten mit der richtigen Aussprache sprechen.
 
Zufall oder kein Zufall?
Der Schalter am iPod shuffle hat drei Einstellungen. Links wird deine Musik zufällig durcheinander gewürfelt. In der Mitte werden deine Songs in der normalen Reihenfolge gespielt. Rechts wird der iPod shuffle ausgeschaltet.
";2;False;0;;;Apple iPod shuffle Tragbarer MP3-Player 4 GB 3. Generation;apple-ipod-shuffle-4-gb-silber;True;True;P-1210;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;79.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39908,3107986111;40;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000220-apple-ipod-shuffle-4-gb-silber.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000221-apple-ipod-shuffle-4-gb-silber.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000222-apple-ipod-shuffle-4-gb-silber.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"AVM FRITZ!Fon 7150 ";"AVM FRITZ!Fon 7150 Fritz!Box Router +Telefon + VOiP ";"
FRITZ!Fon 7150 vereint VoIP-/Festnetz- Telefonanlage, DSL-Modem, WLAN-Router und DECT-Telefon in einem Gerät.

FRITZ!Fon 7150 kann alles, was eine FRITZ!Box auszeichnet und bringt noch ein DECT-Mobilteil mit. Das Multitalent bietet Festnetz- und Internettelefonie, schnelles Surfen im Internet und kabellosen DSL-Zugang in einem Gerät. Telefongespräche können wahlweise über Internet (Voice over IP) oder Festnetz geführt werden – auch bei ausgeschaltetem Computer. Das zugehörige Mobilteil bietet alle Vorteile der Schnurlostelefonie über DECT. Die Anmeldung von weiteren Mobilteilen an der Basisstation ist problemlos möglich. Bereits vorhandene ISDNTelefone oder ISDN-TK-Anlagen lassen sich ohne weiteres an FRITZ!Fon 7150 anschließen.
 
Durch die Router-Funktion erhalten alle PCs im Netzwerk Zugang zum Internet über LAN und WLAN. Die WLAN-Funkverbindungen sind ab Werk mit dem sicheren WPA-Standard verschlüsselt und dank der Stick & Surf-Funktion von AVM erfolgt die Konfiguration automatisch. Über die USB-Schnittstelle können auch USB-Drucker und -Speichermedien für die gemeinsame Nutzung komfortabel vernetzt werden. Die Hard- und Software-Firewall schützt alle Geräte im Netzwerk vor Angriffen von außen. Zusätzliche Komfortfunktionen der FRITZ!Fon 7150 wie Nachtschaltung, Klingelsperre oder ein Mailservice ergänzen die Komplettlösung für Telefonie und Internet.
 
Internettelefonie mit Festnetzqualität
Intelligentes Codec Management sorgt für eine konstante Sprachqualität beim VoIPen. Dank Bandbreitenmanagement surfen Sie gleichzeitig mit optimaler Qualität im Internet, ohne dass Internettelefonate gestört werden. Mit zwei Mobilteilen an der Station sind auch zwei Gespräche gleichzeitig schnurlos möglich – eines als Festnetz- und eines als Internettelefonat. Neben der exzellenten Sprachqualität bietet FRITZ!Fon 7150 auch bei Internettelefonie ISDN-Leistungsmerkmale wie Makeln, Anklopfen, Rufnummernanzeige, Direktruf oder Dreierkonferenz. Bis zu 10 verschiedene VoIP-Rufnummern – auch unterschiedlicher Provider – lassen sich speichern.
 
Schnurloses Telefonieren mit DECT-Komfort
Das DECT-Mobilteil bietet neben einem Farbdisplay mit grafischer Darstellung und einem digitalen Anrufbeantworter ein Telefonbuch für 200 Einträge. Sowohl das Adressbuch als auch die Anrufliste lassen sich bequem über das Mobilteil pflegen. Das ist mit einer Gesprächszeit von bis zu 17 Stunden selbst langen Telefonaten gewachsen. Über das bei DECT eingesetzte GAP-Profil lassen sich bis zu fünf weitere Mobilteile anmelden.
 
WLAN – sicher und schnell
FRITZ!Fon 7150 bietet bereits ab Werk eine sichere WLAN-Verbindung dank aktivierter WPA-Verschlüsselung. Mit der von AVM entwickelten Stick & Surf-Technologie wird der Start ins kabellose Surfen vereinfacht. Sobald der FRITZ!WLAN Stick in den USBHost der FRITZ!Fon 7150 gesteckt wird, werden die Konfigurations- und Sicherheitseinstellungen automatisch zwischen beiden Geräten abgeglichen. FRITZ!Fon 7150 unterstützt die neuesten WLAN-Standards und ermöglicht Verbindungen bis zu 125 MBit/s. Auf Wunsch lässt sich WLAN per Tastendruck an der Basisstation abschalten.
 
";2;False;0;;;"AVM FRITZ!Fon 7150 (Fritz!Box Router +Telefon + VOiP) ";avm-fritzfon-7150;True;True;P-2760;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;169.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39907,7783680556;20;34;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000218-avm-fritzfon-7150.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000219-avm-fritzfon-7150.jpg;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"AVM FRITZ!Fon MT-D VoIP Dect-Telefon ";"AVM FRITZ!Fon MT-D VoIP Dect-Telefon ";"
FRITZ!Fon MT-D: HD-Telefonie und komfortable Internetdienste mit DECT.
Telefonieren Sie mit dem Schnurlostelefon FRITZ!Fon MT-D in bestechender Qualität über das Internet und nutzen Sie komfortable Webdienste. Als intelligentes Telefon der neuesten DECT-Generation vereint das FRITZ!Fon den Komfort der schnurlosen Telefonie mit den Qualitäts- und Leistungsmerkmalen der Internettelefonie (VoIP) in einem Gerät.
 
Bei der Internettelefonie mit einem FRITZ!Fon wird durch HD-Telefonie (High Definition) ein brillantes, natürliches Klanggefühl erreicht. Sprache lässt sich mit dem FRITZ!Fon in ihrem gesamten Frequenzspektrum wiedergeben, was die Klangqualität von Festnetzverbindungen deutlich übertrifft.
 
FRITZ!Fon unterstützt die übertragung großer Bandbreiten. Dies ermöglicht neben HD-Telefonie auch die Nutzung komfortabler Internetdienste wie den Empfang von E-Mails, Podcasts, RSS-Feeds und Internetradio.
 
Die FRITZ!Box-Modelle FRITZ!Box Fon WLAN 7390, 7320, 7270 oder 7240 stellen mit der integrierten DECT-Basisstation, mehreren Anrufbeantwortern und einem Telefonbuch mit 300 Einträgen den idealen Partner für das FRITZ!Fon dar. Mit der umfangreichen Prozessor- und Speicherausstattung ist auch der Grundstein für neue Anwendungen gelegt. Denn das FRITZ!Fon ist lernfähig: Als eines der ersten intelligenten Schnurlostelefone wird es auch künftig per Firmware-Updates aktualisiert und um neue Funktionen erweitert werden können.
 
Umfangreicher Komfort
Das FRITZ!Fon MT-D ist mit zahlreichen Komfortfunktionen ausgestattet. Dazu zählen Lauthören und Freisprechen in HD-Qualität sowie ISDN-Leistungsmerkmale wie Namensanzeige bei bekannten Rufnummern, Halten, Makeln, Anklopfen, Rufumleitung oder Dreierkonferenz. Die Internettelefonie in HD-Qualität lässt sich so in ihrem vollen Umfang und Komfort nutzen, ohne dass der Computer eingeschaltet sein muss. FRITZ!Fon informiert zudem aktiv über unbeantwortete Anrufe, Nachrichten auf dem Anrufbeantworter und zeigt eingegangene E-Mails an. An der DECT-Basisstation der FRITZ!Box Fon WLAN 7390, 7320, 7270 und 7240 lassen sich bis zu 6 FRITZ!Fon-Handgeräte oder andere DECT-Telefone anmelden. Die Erstinstallation und individuelle Einstellungen erfolgen dabei bequem über einfache Assistenten.
 
FRITZ!Box als idealer Partner
Das FRITZ!Fon MT-D kann als Mobilteil an jeder DECT-Basisstation eingesetzt werden. Im Zusammenspiel mit der FRITZ!Box Fon WLAN 7390, 7320, 7270 oder 7240 kann jedoch das volle Spektrum der Möglichkeiten beim Telefonieren und Surfen über das Internet ausgenutzt werden. Die FRITZ!Box Fon WLAN 7390 zum Beispiel vereint eine bisher nicht erreichte Vielfalt in einem Gerät: VDSL- und ADSL-Unterstützung, DECT-Basisstation fürs schnurlose Telefonieren sowie WLAN N für die optimale Datenübertragung.
 
Über den Mediaserver sind gespeicherte Filme, Musik und Bilder auch bei ausgeschaltetem Computer im gesamten Netzwerk verfügbar. Darüber hinaus kann der Online-Speicher wie eine lokale Festplatte genutzt werden. So wird die FRITZ!Box Fon WLAN 7390 zur idealen Plattform für vernetzte Anwendungen wie IPTV, Video on Demand oder Mediastreaming.
 
Bedienung
- Einfach einschalten und Suchtaste auf FRITZ!Box drücken.
 
- Einfache Bedienung über intuitives Menü.
 
- Telefonbuch komfortabel über FRITZ!Box-Oberfläche einrichten und anzeigen.
 
- In FRITZ!Box integrierte Anrufbeantworter einfach am FRITZ!Fon MT-D einrichten und abhören.
 
- Blinkende Leuchtdiode signalisiert eingegangene Anrufe, neue Nachrichten auf dem Anrufbeantworter und neue E-Mails.
 
- Große Schrift und große Tasten.
";2;False;0;;;"AVM FRITZ!Fon MT-D VoIP Dect-Telefon ";avm-fritzfon-mt-d-voip-dect-telefon;True;True;;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;49.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39907,7759837963;20;34;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000213-avm-fritzfon-mt-d-voip-dect-telefon.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000214-avm-fritzfon-mt-d-voip-dect-telefon.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000215-avm-fritzfon-mt-d-voip-dect-telefon.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"AVM FRITZ!WLAN USB Stick ";"AVM FRITZ!WLAN USB Stick - mit Stick & Surf Wireless LAN ";"
AVM FRITZ!WLAN USB Stick - mit Stick & Surf Wireless LAN
 
Allgemein / Breite [cm]: 2
Allgemein / Formfaktor: Extern
Allgemein / Gerätetyp: Netzwerkadapter
Allgemein / Gewicht [g]: 10
Allgemein / Höhe [cm]: 1.1
Allgemein / Schnittstellentyp (Bustyp): Hi-Speed USB
Allgemein / Tiefe [cm]: 5.3
Antenne / Antenne: Intern eingebaut
Erweiterung-Konnektivität / Verbindungen: 1 x Hi-Speed USB - USB Typ A, 4-polig
Kopf / Hersteller: AVM
Kopf / Kompatibilität: PC
Kopf / Modell: USB Stick
Kopf / Paketierte Menge: 1
Kopf / Produktlinie: AVM FRITZ!WLAN
Netzwerk / Anschlusstechnik: Drahtlos
Netzwerk / Data Link Protocol: IEEE 802.11n;IEEE 802.11b;IEEE 802.11g
Netzwerk / Datenübertragungsrate [Mbps]: 150
Netzwerk / Frequenzband: 2.4 GHz
Netzwerk / Leistungsmerkmale: Stromversorgung über USB;Wi-Fi Protected Setup (WPS);Firmware aktualisierbar
Netzwerk / Produktzertifizierungen: IEEE 802.11n;IEEE 802.11g;USB 2.0;USB 1.1;IEEE 802.11b;IEEE 802.11i
Netzwerk / Statusanzeiger: Link/Aktivität
 
Software-Systemanforderungen / Erforderliches Betriebssystem:
 
Microsoft Windows XP SP2;Microsoft Windows 7;Microsoft Windows Vista
Software-Systemanforderungen / Software inbegriffen: Treiber & Utilities
Verschiedenes / Encryption Algorithm: WPA2;128-Bit WEP;64-Bit WEP;WPA
Verschiedenes / Enthaltene Kabel: 1 x USB-Kabel ( extern ) - 90 cm
";2;False;0;;;"AVM FRITZ!WLAN USB Stick N Standard 300MBit/Sek ";avm-fritzwlan-usb-stick;True;True;P-2720;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;39.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39907,7691203704;19;34;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000208-avm-fritzwlan-usb-stick.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000209-avm-fritzwlan-usb-stick.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000210-avm-fritzwlan-usb-stick.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Navigon Schutztasche 21|12|22|13|23 Serie ";"Navigon Schutztasche 21|12|22|13|23 Serie ";"

Navigon Schutztasche 21|12|22|13|23 Serie

 
Diese Tasche schützt Ihren PNA vor Schmutz, Kratzern und Stößen.
Einfach den PNA in die Tasche stecken. Textiltasche mit Zipper
";2;False;0;;;;navigon-schutztasche-2112221323-serie;True;True;P-2140;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;24.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39887,5982523148;68;14;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000197-navigon-schutztasche-2112221323-serie.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Hama MP3-Tasche für Sansa Clip;Hama MP3-Tasche für Sansa Clip;

Hama MP3-Tasche für Sansa Clip

passgenaue Silikontasche, sitzt wie eine zweite Haut
Farbe: Transparent
Ausstattung:
rutschfeste Oberfläche
Aussparung für Kabelverbindungen
;2;False;0;;;Hama MP3-Tasche für Sansa Clip;hama-mp3-tasche-fuer-sansa-clip;True;True;P-1580;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;14.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39881,6482638889;52;8;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000196-hama-mp3-tasche-fur-sansa-clip.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Apple iPod Nano 16 GB silber;Apple ipod nano 16 GB silber mit Kamera;"
Apple ipod nano 16 GB silber mit Kamera
 
Der neue iPod nano. Jetzt mit Videokamera, Gehäuse aus poliertem Aluminium und einem größeren Display und dem neuen FM Radio mit Live-Pause.
 
Neues gebogenes Design, der dünnste iPod, den es je gab mit neun Farben zu Auswahl
Die Bedieung optimiert: ein einziges Handschütteln und ein anderes Lied wird gespielt
Die neue Funktion ""Genius"" findet die Songs in Ihrer Mediathek, die besonders gut zusammenpassen, und erstellt daraus eine Genius Wiedergabeliste.
Viele Abspielformate: z.B. MP3, AAC, Apple Lossless, AIFF, WAV, H.264, MPEG-4
Lieferumfang: iPod Nano, Ohrhörer, USB 2.0 Kabel, Dock-Adapter, Dokumentation, iTunes 9.0
 
Vom beliebtesten Musikplayer der Welt gibt es jetzt noch mehr zu sehen.Vom beliebtesten Musikplayer der Welt gibt es jetzt noch mehr zu sehen.Ein Wettrennen mit Einkaufswagen. Der große Food Fight um das Essen in der Mensa. Jetzt kannst du all das mit der iPod nano Videokamera festhalten. Nimm hochwertige Videos im Hoch- oder Querformat auf, die du ganz einfach ins Web stellen oder an Freunde mailen kannst. Über das im iPod nano integrierte Mikrofon wird das Audiomaterial aufgenommen, das du dann beim Abspielen über die integrierten Lautsprecher hörst.
 
nano macht video
Der neue iPod nano. Jetzt mit Videokamera, Gehäuse aus poliertem Aluminium und einem größeren Display. Und dem neuen FM Radio mit Live-Pause.
 
Mach überall zur Filmkulisse
Den iPod nano gibt's jetzt mit integrierter Videokamera, mit der Sie überall alles spontan festhalten und dann mit deinen Freunden im Internet teilen können. Diese Videokamera ist so klein, dass Sie sie überallhin mitnehmen können.
 
Videoaufnahme. So nano kann Video sein
Blättern Sie durch das Menü zur Videokamera und schon können Sie Videos im Hoch- oder Querformat aufnehmen - ideal zum Mailen oder Posten auf Facebook oder MobileMe. Mit dem integrierten Mikro können Sie auch Ton aufnehmen. Wenn Sie dann Ihr Video auf dem iPod nano abspielen, hören Sie den Ton gleich dazu. Damit wird Ihr Immer-dabei-Musikplayer zur Immer-dabei-Videokamera.
 
Special Effects Abteilung inklusive
15 tolle Videoeffekte geben Ihren Videos richtigen Hollywood-Touch. Blättern Sie durch die Effekte, wählen Sie den passenden aus, z. B. Filmkörnung oder Bewegungsunschärfe, und dann Kamera ab! Wenn Sie fertig sind, synchronisieren Sie den iPod nano mit Ihrem Computer und iPhoto (oder eine andere Foto-Software) wird geöffnet. Jetzt brauchen Sie Ihren Videohit nur noch zu mailen oder auf YouTube oder Facebook zu posten.
 
Synchronisieren - Teilen - Und noch mehr Videos auf YouTube laden
Wenn Sie den iPod nano an Ihren Mac anschließen, wird iPhoto geöffnet und alle mit dem iPod nano gemachten Videos werden mit Ihrem Computer synchronisiert. Auf dem PC geht das mit Ihrer Fotosoftware genauso einfach. Auf einem Mac können Sie Ihre Videos dann direkt in iPhoto durchsuchen und bearbeiten. Die Dateigrößen der Videos sind perfekt geeignet, um sie auf YouTube hochzuladen oder an Freunde zu mailen.
 
Das ist Genius
Steuern Sie Genius selbst. Oder Sie lassen ihm einfach freien Lauf. Egal, wofür Sie sich entscheident, Genius durchsucht Ihr Musikarchiv nach Songs, die gut zusammenpassen.
 
Genius Wiedergabelisten
Angenommen Sie haben einen Lieblingssong und möchten weitere Titel hören, die gut dazu passen. Ein paar Klicks auf den iPod nano und Genius sucht anhand dieses Songs weitere Titel in Ihrem Musikarchiv und erstellt eine Genius Wiedergabeliste für Sie. Sie können sie sich sofort anhören, für später speichern oder aktualisieren und nochmal gucken, was dabei rauskommt. Wenn Sie Songmixes suchen, an die Sie selbst nie gedacht hätten, dann überlassen Sie das ruhig Genius.
 
Genius Mixe
Und es gibt noch eine tolle Möglichkeit, eine ganz persönliche Songsammlung auf den iPod nano zu bekommen und Genius alles für Sie erledigen zu lassen: Die Genius Mixe. Sie müssen dafür nur den iPod nano mit iTunes synchronisieren. Genius durchsucht dann automatisch Ihr Musikarchiv nach Songs, die gut zusammenpassen und erstellt bis zu 12 Genius Mixe. Diese genrebasierten Mixe sind wie Radiosender, die nur Ihre Musik spielen. So entdecken Sie Songs wieder, die Sie schon ewig nicht mehr gehört haben oder welche, die Sie schon ganz vergessen hatten.
 
Das ist so Cover Flow
Blättern Sie mit Cover Flow durch Ihre Alben, um ganz schnell den richtigen Song zu finden. Oder halten Sie die Mitteltaste gedrückt, um das Albumcover umzudrehen und die Songs zu sehen. Wenn Sie den gewünschten Song gefunden haben, drücken Sie auf die Mitteltaste, um ihn zu Ihrer On-the-Go-Wiedergabeliste hinzuzufügen.
 
Zum Mischen schütteln
Hören Sie Songs einfach mal nach dem Zufallsprinzip. Einfach die Schüttelfunktion aktivieren, den iPod nano kurz schütteln und schon springt er zu irgendeinem anderen Song. Lassen Sie sich überraschen, was der iPod nano als nächstes für Sie auflegt.
 
Radio hören - Radio anhalten. Radio weiterhören
Der neue FM Tuner zeigt Ihnen die Namen von Songs und Interpreten. Und mit der fantastischen neuen Live-Pause Funktion ist Radio hören noch besser als Radio hören.
 
FM Radio. Noch eine Möglichkeiten zu rocken
Im Radio läuft immer gute Musik. Und mit dem FM Tuner können Sie Ihre Lieblingssendungen jetzt auf dem Weg zur Arbeit hören oder neue Musik entdecken, während Sie im Fitnessstudio rocken. Sie sehen sogar was und wen Sie gerade hören.
 
Mit Live-Pause nie mehr einen Beat verpassen
Angenommen Sie müssen Ihre Lieblingssendung im Radio einmal kurz unterbrechen. Ein Klick auf den iPod nano und schon ist Pause. Noch ein Klick und Sie hören die Sendung weiter. Sie können sogar bis zu 15 Minuten zurückspulen und dann vorspulen, um wieder live dabei zu sein.
 
VoiceOver. Spricht jeden an
VoiceOver sagt Ihnen die Namen von Titel und Interpreten der Songs, die Sie gerade hören. Und zwar so gut, dass Sie überrascht sein werden.
 
Lass mal VoiceOver reden
Sie hören einen Song und wollen wissen, wie er heißt oder von wem er ist? Benutzen Sie einfach das Click Wheel oder die Steuerung an den optionalen Apple Earphones mit Fernbedienung und Mikro, damit VoiceOver Ihnen Songtitel und Interpreten sagt, ohne dabei die Musik zu unterbrechen. Sie müssen nicht mehr auf das Display schauen, sondern können sich aufs Joggen oder Radfahren konzentrieren.
 
So funktioniert's
VoiceOver funktioniert ganz einfach. Wir haben hart daran gearbeitet, damit der iPod nano nicht nur spricht, sondern auch genau das Richtige sagt. Alles beginnt mit iTunes und der engen Zusammenarbeit mit dem iPod nano. iTunes liest zunächst die Songinformationen, und verwendet dann das VoiceOver Kit, um Ansagen für Songs, Interpreten und Wiedergabelisten zu erstellen. Sie müssen einfach nur deinen iPod nano mit deinem Computer synchronisieren und schon spricht er mit Ihnen.
 
Das Sprachtalent
Dein Musikarchiv enthält Musik aus allen Ländern der Welt: Chansons aus Frankreich, Sambarhythmen aus Brasilien und Popmusik aus Japan. Zum Glück spricht VoiceOver fließend Songisch.
iTunes wählt automatisch die Sprache und die beste Stimme für die Songtitel und Interpreten aus. Die Software analysiert Songdaten wie Titel, Interpreten und Albuminfos und nutzt dann intelligente Algorithmen, um die richtige Sprache auszuwählen. ""Ya Viene el Sol"" von Ozomatli erkennt iTunes zum Beispiel als spanischen Song - und schon spricht der iPod den Songtitel und Interpreten automatisch auf Spanisch aus. Sie wollen es lieber in einer anderen Sprache hören? Dann können Sie die VoiceOver Sprache für diesen Song natürlich in iTunes ändern.
 
Geht sofort los
Mit dem Nike + iPod Sport Kit und einem integrierten Schrittzähler, das Ihre Fortschritte verfolgt und Sie motiviert, wird das Training mit dem iPod nano nie zur Routine.
 
Der erste Schritt in Richtung Fitness
Der iPod nano ist sowieso schon Ihr ständiger Begleiter, warum sollten Sie ihn also nicht auch als Fitnesstrainer nutzen? Denn jetzt wird er auch zum Schrittzähler. Mit dem integrierten Beschleunigungssensor zählt er Ihre Schritte, damit Sie Ihr Fitnessziel nie aus den Augen verlieren. Sie können eine tägliche Schrittvorgabe festlegen oder ""Immer eingeschaltet"" wählen, damit er jeden Ihrer Schritte zählt. Das macht den iPod nano zum idealen Trainingspartner.
 
Rock'n'Run
Mit dem iPod nano und Ihren Laufschuhen holen Sie alles aus Sich raus. Sehen Sie wie die Minuten verfliegen und Sie Kilometer für Kilometer zurücklegen. Sie bekommen Sprachfeedback in Echtzeit und hören dabei Ihren Lieblingsmusik und den PowerSong, der Sie jedes Mal wieder antreibt, Ihr Bestes zu geben.
 
Rock das Training
Nehmen Sie Nike + iPod mit ins Fitnessstudio und Sie werden Minute für Minute, Kilometer für Kilometer durch mehr als nur Musik motiviert. Schließen Sie den iPod nano an ein Fitnessgerät an, das mit Nike + iPod kompatibel ist. Halten Sie die Geschwindigkeit, die Dauer und die Laufstrecke deines Trainings fest. Mit dem iPod nano wird jeder Besuch im Fitnessstudio zur neuen Herausforderung.
 
Synchronisieren
Wenn Sie fertig sind, schließen Sie den iPod nano an Ihren Mac oder PC an. Ihre Workout-Daten werden dann automatisch von iTunes an nikeplus.com gesendet. Dort können Sie dann alle Ihre Workouts und Läufe überprüfen. Holen Sie außerdem neue Motivation für den nächsten Lauf mit empfohlenen Zielvorgaben, persönlichen Trainingsprogrammen und Karten mit neuen Strecken, die Sie ausprobieren können. Oder tauschen Sie sich mit Läufern aus aller Welt aus.
";2;False;0;;;Apple ipod nano 16 GB schwarz;apple-ipod-nano-16-gb-silber;True;True;P-1380;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;159.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39876,6815625;48;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000087-apple-ipod-nano-8-gb-verschiedene-farben.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000076-apple-ipod-nano-8-gb-verschiedene-farben.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000077-apple-ipod-nano-8-gb-verschiedene-farben.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Griffin Sports Tempo Armband für iPod nano ";"Griffin Sports Tempo Armband für iPod nano ";"

Griffin Sports Tempo Armband für iPod nano  

 
Mit dem Tempo Armband von Griffin ist der iPod Nano sicher geschützt und doch immer erreichbar
Egal, ob Sie wandern, joggen, reiten, Kanu fahren, Fallschirm springen, im Garten werkeln oder sich einfach nur zu Hause entspannen.

Das formschöne, unauffällige Design mit Reflektorstreifen sorgt für hohe Sichtbarkeit. 
Eine Aufwicklung für das Kopfhörerkabel sorgt dafür, dass Kabelsalat vermieden wird. 
Tempo ist mit einer Abdeckung zum Schutz des iPod Displays und einem weichen Innenfutter ausgestattet.
Das Armband ist für alle Größen gut geeignet und in der Waschmaschine waschbar.
";2;False;0;;;"Griffin Tempo Sports Armband ";griffin-sports-tempo-armband-fuer-ipod-nano;True;True;P-1530;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;35.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39876,600787037;51;28;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000195-griffin-sports-tempo-armband-fur-ipod-nano.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Artwizz SeeJacket Crystal Case für iPod Nano 4G;Artwizz SeeJacket Crystal Case für iPod Nano 4G transparent;"

Artwizz SeeJacket Crystal Case für iPod Nano 4G transparent

 
Funktionale Schutzhülle aus Polycarbonat - Kristallklare Schutzhülle, speziell für iPod nano 4G
Hochwertige, robuste und transparente Schutzhülle
Komplettschutz für Vorder- und Rückseite (inkl. Display)
Anschlüsse sind ausgespart
Keine Beeinträchtigung der Bedienbarkeit des iPod nano 4G.
";2;False;0;;;Artwizz SeeJacket Crystal Case für iPod Nano 4G;artwizz-seejacket-crystal-case-fuer-ipod-nano-4g;True;True;P-1440;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;19.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39860,7781828704;51;30;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000194-artwizz-seejacket-crystal-case-fur-ipod-nano-4g.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Belkin F8Z 409 Silikonhülle für Apple iPod Classic ";"Belkin F8Z 409 Silikonhülle für Apple iPod Classic ";"

Belkin F8Z 400 Silikonhülle für Apple iPod Classic

schwarz/blau/rosa 3er-Pack

iPod Classic SILICON SLEEVE 3-PACK Schwarz & Blau & Pink
";2;False;0;;;;belkin-f8z-409-silikonhuelle-fuer-apple-ipod-classic;True;True;P-1430;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;14.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39860,7754166667;51;;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000193-belkin-f8z-409-silikonhulle-fur-apple-ipod-classic.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Garmin DVD City Navigator Europa NT Update 2010;Garmin DVD City Navigator Europa NT Update 2010;"

Garmin DVD City Navigator Europa NT Update 2010

Der City Navigator Europa NT 2010 bietet einen erhöhten Detailgrad
mit über 8 Millionen km Straßenabdeckung in Europa
 
Volle Länderabdeckung für die Baltischen Staaten + erweiterte Straßenabdeckung
von Griechenland, Kroatien, Tschechien, Ungarn, Polen, Slowakei
 
1,2 Millionen POIs und 1 Millionen Städte, Orte und Dörfer,
über 8.000 Campingplätze in West-Europa
Update der zulässigen Höchstgeschwindigkeiten
Lieferumfang: DVD mit City Navigator Europa NT
";2;False;0;;;Garmin DVD City Navigator Europa NT Update 2009;garmin-dvd-city-navigator-europa-nt-update-2010;True;True;P-2020;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;99.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39856,6709722222;67;44;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000192-garmin-dvd-city-navigator-europa-nt-update-2010.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Sony MDR EX 35 LPB.AE Stereo-In-Ear-Kopfhörer schwarz ";"Sony MDR EX 35 LPB.AE Stereo-In-Ear-Kopfhörer schwarz ";"

Sony MDR EX 35 LPB.AE Stereo-In-Ear-Kopfhörer schwarz

 
Leistungsstarke Kopfhörer, hervorragend geeignet als Ersatz für mp3-Player-Kopfhörer der Einstiegsklasse.>Leistungsmerkmale
Hybrid-Silikon-Ohrpolster für sicheren Halt und Langzeit-Tragekomfort
Y-förmiges Kabel mit praktischem Kabel- Reiter zur Vermeidung von Kabelsalat
Frequenzgang: 6-23,000Hz
3,5mm Klinkenanschluss
Kabel: 1,2Y-förmig
 
Zubehör: Ohrpolster, Kabel-Reiter
";2;False;0;;;"Sony MDR EX 35 LPB.AE Stereo-In-Ear-Kopfhörer schwarz ";sony-mdr-ex-35-lpbae-stereo-in-ear-kopfhoerer-schwarz;True;True;P-1500;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;24.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39816,7113541667;51;10;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000187-sony-mdr-ex-35-lpbae-stereo-in-ear-kopfhorer-schwarz.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Creative EP 630 Ohrhörer schwarz ";"Creative EP 630 Ohrhörer schwarz ";"

Creative EP 630 Ohrhörer schwarz

 
Silikon-Ohrpolster schirmen Umgebungsgeräusche effektiv ab und verbessern die Basswiedergabe
Leicht und komfortabel - für maximalen Musikgenuss unterwegs
Sauerstofffreie Kupferkabel für verlustfreie Signalübertragung
Lieferumfang: 1 Paar In-Ear-Ohrhörer mit Silikon-Ohrpolstern,
2 Paar zusätzliche Silikon-Ohrpolster in verschiedenen Größen
";2;False;0;;;"Creative EP 630 Ohrhörer ";creative-ep-630-ohrhoerer-schwarz;True;True;P-1470;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;19.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39816,7078009259;51;22;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000186-creative-ep-630-ohrhorer-schwarz.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Sandisk Sansa Fuze 4 GB;"Sandisk Sansa Fuze MP3-/Video-Player 4 GB mit Radio ";"

Sandisk Sansa Fuze MP3-/Video-Player 4 GB mit Radio

 
 
Mit der verfügbaren Akkuleistung können Sie 24 Stunden lang Musik hören, Bilder anschauen oder spielen.
Der neue Sansa Fuze von SanDisk ist der ideale tragbare Musikplayer für Sie.
Er steht mit einer Speicherkapazität 4 GB in schwarz,rot,pink zur Verfügung.
Sehen Sie sich Ihre Lieblingsvideoclips auf dem 1,9""-Farbdisplay des Sansa Fuze an.
Lauschen Sie dem FM-Radio mit 40 voreingestellten Sendern oder probieren Sie den integrierten Sprachrekorder aus. Mit einer unglaublich starken Akkuleistung in einem 0,3"" schmalen Gerät setzt der Sansa Fuze Zeichen.
";2;False;0;;;Sandisk Sansa Fuze MP3-/Video-Player 4 GB mit Radio;sandisk-sansa-fuze-4-gb;True;True;P-1560;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;89.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39789,5565625;52;8;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000180-sandisk-sansa-fuze-4-gb.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Sandisk Sansa Clip 2 GB schwarz;Sandisk Sansa Clip 2 GB mit integriertem FM-Tuner;"

Sandisk Sansa Clip 2 GB mit integriertem FM-Tuner blau, rot, schwarz, pink

digitaler SanDisk Player für MP3, WMA, Secure WMA und FM Radio
kleines, kompaktes Design, kaum größer als eine Streichholzschachtel
FM-Radio mit 40 Stationsspeicherplätzen
Diktiergerät-Funktion über integriertes Mikrofon
4-zeiliges OLED-Display
Sortierung der Titel nach versch. Kriterien möglich, wie z.B. Künstler, Album, Genre, u.a.
bis zu 15-h-Wiedergabe mittels internem, wiederaufladbaren Akku
inkl. abnehmbarem Trageclip, Ohrhörer, USB 2.0 Kabel, Installations-CD mit Bedienungsanleitung
unterstützt Win 2000 / XP / Vista
 
Lieferumfang:
Player inkl. abnehmbarem Trageclip, Ohrhörer, USB 2.0 Kabel, Installations-CD mit Bedienungsanleitung
";2;False;0;;;"Sandisk Sansa Clip 2 GB mit integriertem FM-Tuner ";sandisk-sansa-clip-2-gb-schwarz;True;True;P-1550;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;49.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39789,5530092593;52;8;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000163-sandisk-sansa-clip-8-gb-schwarz.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Sandisk Sansa Clip 8 GB schwarz;"Sandisk Sansa Clip 8 GB mit integriertem FM-Tuner ";"

Sandisk Sansa Clip 8 GB mit integriertem FM-Tuner schwarz

 
digitaler SanDisk Player für MP3, WMA, Secure WMA und FM Radio
kleines, kompaktes Design, kaum größer als eine Streichholzschachtel
FM-Radio mit 40 Stationsspeicherplätzen
Diktiergerät-Funktion über integriertes Mikrofon
4-zeiliges OLED-Display
Sortierung der Titel nach versch. Kriterien möglich, wie z.B. Künstler, Album, Genre, u.a.
bis zu 15-h-Wiedergabe mittels internem, wiederaufladbaren Akku
inkl. abnehmbarem Trageclip, Ohrhörer, USB 2.0 Kabel, Installations-CD mit Bedienungsanleitung
unterstützt Win 2000 / XP / Vista
 
Lieferumfang:
Player inkl. abnehmbarem Trageclip, Ohrhörer, USB 2.0 Kabel, Installations-CD mit Bedienungsanleitung
";2;False;0;;;"Sandisk Sansa Clip 8 GB mit integriertem FM-Tuner ";sandisk-sansa-clip-8-gb-schwarz;True;True;P-1570;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;69.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39789,5485648148;52;8;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000163-sandisk-sansa-clip-8-gb-schwarz.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Canon PIXMA MP550 Multifunktionsgerät;Canon PIXMA MP550 Multifunktionsgerät;"
Canon PIXMA MP550  Multifunktionsgerät
 
 
3 in 1, Drucken, Kopieren, Scannen
 
 
Der PIXMA MP550 überzeugt als exzellentes Multifunktionssystem für zu Hause mit starkem Preis-Leistungs-Verhältnis.
Er kombiniert Komfort mit Klasse beim Dokumenten- und Fotodruck; hohes Tempo bei Druck, Scan und Kopie sind selbstverständlicher Standard.
 
Drucken, Kopieren und Scannen
Druckgeschwindigkeit: bis zu 9,2/6,0 ISO-Seiten pro Minute (SW/Farbe)
Bis zu 9.600 x 2.400 dpi Auflösung, 1 Picoliter feine Tintentröpfchen; 10 x 15 cm Randlosprint in ca. 39 Sek.
5-Tintensystem
5,0 cm großes TFT-Farbdisplay und Easy-Scroll-Bedienrad
Scanner mit bis zu 2.400 dpi
PictBridge und Speicherkarte
ChromaLife100+
Auto Photo Fix II
";2;False;0;;;Canon PIXMA MP540 Multifunktionsgerät - All in One Drucker - Drucken - Scannen - Kopieren - Faxen;canon-pixma-mp550-multifunktionsgeraet;True;True;P-2200;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;109.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39784,3258333333;"22;2095";25;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000161-canon-pixma-mp550-multifunktionsgerat.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000162-canon-pixma-mp550-multifunktionsgerat.jpg;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;AVM Fritz! WLAN Repeater;AVM Fritz! WLAN Repeater N/G zur Erhöhung der Reichweite von W-LAN Netzen;"
AVM Fritz!WLAN Repeater N/G 

zur Erhöhung der Reichweite von W-LAN Netzen

Erhöht schnell und einfach die Reichweite von WLAN-Netzen
Funktioniert in allen WLAN-Funknetzen: 802.11n Draft 2.0 (300 MBit/s), 802.11g/a (54 MBit/s)
und 802.11b (11 MBit/s)
 
Sichere Funkverbindungen dank WPA2-, WPA- und WEP-Verschlüsselung
Integrierter UKW-Minisender (FM-Transmitter 87,5-108 Mhz)
Perfekt abgestimmt auf WLAN-Produkte der FRITZ!Box-Familie
.
";2;False;0;;;AVM Fritz!WLAN Repeater N/G zur Erhöhung der Reichweite von W-LAN Netzen;avm-fritz-wlan-repeater;True;True;P-2730;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;89.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39775,5815509259;19;34;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000157-avm-fritz-wlan-repeater.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000158-avm-fritz-wlan-repeater.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000159-avm-fritz-wlan-repeater.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Adobe Photoshop Elements 7;Adobe Photoshop Elements 7 deutsch WIN.;"
Adobe Photoshop Elements 7 deutsch WIN

Adobe Photoshop Elements 7 kombiniert Leistungsfähigkeit mit einfacher Bedienung,
sodass Ihnen bei der Bearbeitung von Fotos keine Grenzen gesetzt sind.
Machen Sie aus alltäglichen Motiven eindrucksvolle Kunstwerke. Innovative Werkzeuge und Funktionen ermöglichen es Ihnen zum Beispiel,
unerwünschte Objekte mühelos aus einem Foto zu entfernen, mit einer einzigen Mausbewegung gleichzeitig einen Bildbereich auszuwählen und mit Effekten zu versehen,
Zähne aufzuhellen oder einen Himmel noch intensiver wirken zu lassen. Professionell gestaltete Layouts erleichtern Ihnen die Erstellung von Bildbänden,
Fotoalben und interaktiven Online-Galerien, und dank der durchdachten Verwaltung finden Sie jedes Foto im Handumdrehen.
Die wichtigsten Merkmale:
Intuitive Bearbeitungswerkzeuge zur Gestaltung eindrucksvoller Fotoprojekte
Einfache Erstellung unverwechselbarer Kreationen für Print und Web
Effizientes Suchen und Aufrufen von Fotos
";2;False;0;;;Adobe Photoshop Elements 7;adobe-photoshop-elements-7;True;False;P-3010;;;False;0;False;;False;False;0;False;0;1;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;1;0;True;False;10;0;1;1;False;1;10000;;False;True;False;False;109.5000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39774,9070023148;31;20;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000155-adobe-photoshop-elements-7.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000156-adobe-photoshop-elements-7.jpg;;2;;False;ounce;;;;False;False;False;;;;;False;;;;;; -5;0;True;"NAVIGON 1300 Navigationssystem D-A-CH ";"NAVIGON 1300 Navigationssystem D-A-CH ";"

NAVIGON 1300 Navigationssystem D-A-CH

 
NAVIGON MyRoutes, Clever Parking , POI Klick, Fahrspurassistent Pro, Reality View Light
 
 
NAVIGON 1300 Besonders klein und trotzdem voll mit Features.
Die NAVIGON 13er-Serie kann viel mehr, als Sie vielleicht im ersten Moment denken.
Denn in dem kleinen smarten Gehäuse stecken überaus nützliche Funktionen.
Zum Beispiel NAVIGON MyRoutes, das Ihnen jederzeit genau die Route empfiehlt, die zu Ihnen und Ihrem Fahrstil passt.
Für eine schnelle und sichere Navigation sorgen zudem ein verbesserter Fahrspurassistent Pro, Reality View Light und viele weitere Helfer.
 
NAVIGON MyRoutes
Je nachdem, welcher Fahrertyp Sie sind, empfiehlt Ihnen NAVIGON MyRoutes die beste Route – zugeschnitten auf Ihren persönlichen Fahrstil,
den Wochentag und die Tageszeit. Darüber hinaus zeigt Ihnen Ihr NAVIGON bis zu zwei weitere Routen.
Das schafft Transparenz. Sie entscheiden, ob Sie unserer Empfehlung folgen oder eine der Alternativen wählen.
 
Clever Parking
hilft Ihnen bei der Parkplatzsuche. Kurz vor Ihrem Ziel zeigt Ihnen Clever Parking Parkplätze in der näheren Umgebung an.
In Deutschland werden Sie sogar über Parkgebühren informiert. So vermeiden Sie langes Suchen und sparen dabei Geld.
 
Fahrspurassistent Pro
hilft Ihnen selbst durch den hektischsten Straßenverkehr hindurch.
Vorausschauend und übersichtlich zeigt er Ihnen an, auf welche Fahrspur Sie für Ihren nächsten und übernächsten Abbiegepunkt wechseln müssen.
 
POI-Klick
ermöglicht durch Anklicken die Auswahl eines auf der Karte angezeigten Sonderziels wie zum Beispiel Rastplätze oder Sehenswürdigkeiten.
Inklusive wissenswerter Informationen wie Adresse, Öffnungszeiten und Telefonnummern. Und auf Wunsch können Sie sich direkt dorthin navigieren lassen.
 
Lieferumfang:
PNA  1300 (3,5"" im 4:3 Format) | Kurzanleitung | Kfz-Ladekabel | Halterung | Vorinstalliertes Kartenmaterial | USB-Kabel
";2;False;0;;;;navigon-1300-navigationssystem-d-a-ch;True;True;P-2130;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;149.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39760,6629166667;"68;2095";14;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000154-navigon-1300-navigationssystem-d-a-ch.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Digitus USB2.0 Hub 7-port;Digitus USB2.0 Hub 7-port;

Digitus USB2.0 Hub 7-port

USB 2.0 und USB 1.1 kompatibel 7 x USB A Buchse (USB 1.1 und 2.0 Endgeräte
Maximale Datenübertragungsrate 480 Mbps
Überspannungsschutz an allen Ausgängen
Kompatibel mit PC und MAC
Lieferung inklusive USB Anschlusskabel und Netzteil
;2;False;0;;;Digitus USB2.0 Hub 7-port;digitus-usb20-hub-7-port;True;True;P-0045;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;20.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39757,6835532407;26;;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000153-digitus-usb20-hub-7-port.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Logitech USB Hub 4-Port USB;Logitech USB Hub 4-Port USB;"

Logitech USB Hub 4-Port USB

Lieferumfang: Logitech Premium 4-Port USB Hub for Notebooks,
USB-Kabel, Schnellstartanleitung, Etui, Netzteil
 
Systemvoraussetzungen PC: Windows 2000, Windows XP, Windows Vista:
 
USB-Anschluss Mac: Mac OS X (10.1 oder höher) USB-Anschluss
";2;False;0;;;Logitech USB Hub 4-Port USB;logitech-usb-hub-4-port-usb;True;True;P-0072;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;22.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39757,6788425926;26;11;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000152-logitech-usb-hub-4-port-usb.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;LogiLink USB HUB mit Netzteil;"LogiLink USB 2.0 Hub 7-Port mit Netzteil ";"

LogiLink USB 2.0 Hub 7-Port mit Netzteil

 
Der schnelle Hub von LogiLink unterstützt den modernen USB 2.0-Standard mit bis zu 480 MBit/s
und erweitert Ihren Anschluss um weitere 7 Ports.
";2;False;0;;;LogiLink USB HUB mit Netzteil;logilink-usb-hub-mit-netzteil;True;True;P-0070;;;False;0;False;;False;False;0;False;0;1;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;17.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39757,6744907407;"26;2095";31;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000151-logilink-usb-hub-mit-netzteil.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Artwizz SeeJacket Crystal Hülle für iPod classic ";"Artwizz SeeJacket Crystal Hülle für iPod classic Vers.2009 ";"

Artwizz SeeJacket Crystal Hülle für iPod classic

80, 120 und 160 GB (2009 & 2010 Version)

 Das SeeJacket Crystal besteht aus robustem, transparentem Kunststoff und schuetzt zuverlaessig
vor Stoessen, Erschuetterung und Abnutzung.
Zugriff auf alle Bedienelemente bleibt natuerlich bestehen.
Eine Befestigungsmoeglichkeit fuer ein Umhaengeband ermoeglicht bequemes Tragen um den Hals.
Das optional einsetzbares Silikon-Pad schuetzt das Click Wheel und laesst weiterhin bequemes Bedienen zu.
";2;False;0;;;Artwizz SeeJacket Crystal Hülle für iPod classic;artwizz-seejacket-crystal-huelle-fuer-ipod-classic;True;True;P-1450;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;29.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39754,7778009259;51;30;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000150-artwizz-seejacket-crystal-hulle-fur-ipod-classic.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Artwizz PowerPlug Steckdose;"Artwizz PowerPlug Steckdose auf USB-Ladegerät ";"

Artwizz PowerPlug Steckdose

 
auf USB-Ladegerät für iPods und USB aufladbare MP3-Player Mit diesem USB-Ladegerät kann man den iPod shuffle oder andere MP3 Player,

beziehungsweise andere USB Geräte, einfach an der Steckdose ohne Computer aufladen
(das Gerät besitzt einen Steckdosenstecker und einen USB-Schnittstelle).
In Verbindung mit dem iPod Dock Connector-auf-USB Kabel
kann man alle iPod Modelle an der Steckdose aufladen.

Technische Daten: Europäischer Netzstecker
Eingang: 100-240V AC, 0,15A, 47-63Hz
Ausgang: 5V DC, 1,0A Lieferumfang: Artwizz PowerPlug Steckdose
";2;False;0;;;Artwizz PowerPlug Steckdose;artwizz-powerplug-steckdose;True;True;P-1460;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;17.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39754,709837963;51;30;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000149-artwizz-powerplug-steckdose.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Sennheiser CX 300 Ohrkanalhörer schwarz;"Sennheiser CX 300 Ohrkanalhörer ";"

Sennheiser CX 300 Ohrkanalhörer

Sennheiser CX 300 Ohrhörer, Kraftvoller, bassbetonter Stereo-Sound
Optimaler Sitz im Ohrkanal durch Ohradapter
in unterschiedlichen Größen (im Lieferumfang enthalten)
Sehr gute Abschirmung von Außengeräuschen
Ideal für MP3-, CD-, DVD- und MD-Player
sowie portable Spielekonsolen mit 3,5-mm-Kopfhörerausgang
 
";2;False;0;;;;sennheiser-cx-300-ohrkanalhoerer-schwarz;True;True;P-1490;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;29.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39754,705462963;51;29;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000148-sennheiser-cx-300-ohrkanalhorer-schwarz.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Gear4 IceBox transparent;Gear4 IceBox für iPod nano 4G, transparent;"
Gear4 IceBox für iPod nano 4G, transparent
 
 
Gear4 IceBox für iPod nano 4G, transparent
Transparente Hülle für iPod nano 4G
";2;False;0;;;Gear4 IceBox transparent;gear4-icebox-transparent;True;True;P-1480;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;24.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39754,6834143519;"51;2095";28;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000147-gear4-icebox-transparent.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Apple iPod Touch 16 GB schwarz;"Apple iPod Touch 16GB schwarz ";"
Apple iPod Touch 32 GB schwarz mit integrierter WiFi Funktion

Der iPod touch kann alles, was du am iPod toll findest. Und noch vielmehr. Schlankes neues Design. Mit seinem fantastisch flachen Edelstahl-Design liegt der iPod touch mit dem 3.5 Zoll Touch-Display jetzt noch besser in der Hand. Mobil im Spiel. Durch revolutionäre Technologien wie das Multi-Touch-Display, der Beschleunigungssensor und 3D-Grafiken macht das Spielen auf dem iPod touch besonders viel Spaß. Schlaue Musik Mit der neuen Funktion ""Genius"" wird der iPod touch zu Deinem superintelligenten, persönlichen DJ.
Nur ein paar Fingertipps, und Genius erzeugt eine Wiedergabeliste mit Songs Deiner Mediathek, die gut zusammenpassen. Internet überall Internetzugang überall, wo ein drahtloses Netzwerk zur Verfügung steht, damit Sie immer mit dabei sind. Multitouch-Oberfläche: Die revolutionäre Technologie des iPhone und die Software Version 3.1 stecken in diesem genialen iPod. Das brillante Breitformat-Display rückt Ihre Videos und Spiele ins beste Licht und dank OpenGL sehen die Spiele jetzt noch besser aus Surfen Sie mit Safari im Web und sehen Sie YouTube Videos auf dem iPod mit integrierter Wi-Fi Funktionalität an. Mit Ihrem iPod touch können Sie im iTunes Wi-Fi Music Store nach Songs suchen, Hörproben abspielen und Titel kaufen.
Lieferumfang: iPod touch, Ohrhörer, USB 2.0 Kabel, Kurzanleitung
 
Schlankes neues Design
Mit seinem fantastisch flachen Edelstahl-Design liegt der iPod touch so gut in der Hand wie nie zuvor. Ebenfalls Eindruck machen der neue Lautstärkeregler und der integrierte Lautsprecher.

Spiele
Speziell auf die iPod touch Technologie zugeschnittene Spiele sind nur noch einen Fingertipp entfernt. Stöbere in hunderten von Spielen im App Store direkt auf Deinem iPod touch, und wenn Du gefunden hast, was Du suchst, kannst Du es einfach laden und dann kann es losgehen.
 
Steuerung per Fingertipp
Viele Spiele auf dem iPod touch nutzen die Multi-Touch-Technologie für besonders exakte Fingertipp-Steuerung der verschiedenen Spielelemente. Beim Schach ziehst Du mit dem Finger die Figuren, bei Würfelspielen bewegst Du die Würfel. Durch Ziehen mit zwei Fingern kannst Du die Anzeige vergrößern und verkleinern, Deine Figur nach links oder rechts drehen, und durch einfaches Antippen triffst Du eine Auswahl.
 
Musik
Blättere in den Albumcovern Deiner Musiksammlung. Erstelle immer wieder neue Genius Wiedergabelisten und erweitere Deine Sammlung aus dem iTunes Wi-Fi Music Store überall, wo ein Wi-Fi-Hotspot in der Nähe ist.
Mit Cover Flow lebt das Flair einer CD- oder Plattensammlung wieder auf. Wer erinnerst sich nicht an das Gefühl beim Durchblättern der Sammlung? Das gibt es jetzt auch auf dem iPod touch: einfach iPod drehen, durch die Cover blättern, ein Album auswählen, fertig. Ein Fingertipp aufs Cover, und schon siehst Du die Titelliste, ein weiterer Tipp spielt die Musik ab, und dabei kannst Du sogar die Songtexte anzeigen.
 
Ein Musikgenie
Stell Dir vor, Du hörst einen Song. Toll wären jetzt andere Titel, die gut dazu passen. Was machst du? Ganz einfach: Du verwendest die neue Funktion ""Genius"". Diese findet die Songs in Deiner Mediathek, die gut zusammenpassen. Du erhältst eine Genius Wiedergabeliste, die Du sofort anhören, sichern oder sogar aktualisieren kannst. Verlass Dich also auf den Genius von iTunes, wenn Du einen Mix willst, auf den Du selbst nicht gekommen wärst.
 
Lautsprecher integriert
Mit dem integrierten Lautsprecher kannst Du Musik und Gespräche ohne Kopfhörer hören – perfekt für zwangloses Hörvergnügen.

Längere Batterielaufzeit
Jetzt kannst Du noch länger rocken (und ansehen und spielen). Der iPod touch hält bis zu 36 Stunden bei Musik oder bis zu 6 Stunden bei Videos durch. Das reicht für drei oder vier Filme zwischen den Ladevorgängen.
 
Internet
Surfe im Internet mit Wi-Fi. Du kannst detailgenaue HTML-E-Mails mit Anlagen empfangen und Wegbeschreibungen und aktuelle Verkehrsinformationen abrufen. Auch als YouTube-Fan entgeht Dir nichts.
 
Überall ins Internet
Der iPod touch ist der einzige iPod mit kabellosem 802.11b/g Internetzugriff. Bei bestehender Wi-Fi-Verbindung kannst Du im Internet surfen und Nachrichten lesen, Sportergebnisse sehen, Rechnungen bezahlen und online einkaufen.
 
Wer suchet, der findet
Der iPod touch synchronisiert Deine Lesezeichen vom PC oder Mac, sodass Du ruck zuck auf Deine Lieblingsseiten zugreifen kannst. Die Google- und Yahoo!-Suche ist schon integriert, sodass Du im Web schnell findest, was Du suchst.
 
Zoom mit Aussicht
Jeden beliebigen Ausschnitt einer Webseite kannst Du vergrößern, indem Du mit dem Finger darauf tippst oder mit zwei Fingern die Anzeige aufziehst. Websites lassen sich im Hoch- oder Querformat anzeigen: einfach den iPod touch um 90 Grad drehen, und schon wird auch die Darstellung der Website gedreht.
 
Eigene Weblinks
Für häufig besuchte Websites, etwa die einer Zeitung, eines Blogs oder eine Sport-Website, kannst Du einfach ein Symbol auf dem Home-Bildschirm erstellen. Deine Lieblingsseiten sind über mit Safari erstellte Weblinks nur einen Fingertipp entfernt.
 
Rock 'n' Run mit Nike+
Im iPod touch ist kabellose Unterstützung für Nike + iPod integriert. Du brauchst nur einen Nike + iPod Sensor in Deinem Schuh, und schon kann's losgehen.
 
Das optimale Lauftraining
Im iPod touch ist jetzt Unterstützung für Nike + iPod integriert. Einfach den Nike + iPod Sensor (separat erhältlich) in den Nike+ Laufschuh einsetzen, und es kann losgehen. Der Sensor überträgt die Laufdaten drahtlos an den iPod touch – er erfasst die gelaufene Zeit, die zurückgelegte Strecke und die verbrauchten Kalorien. Außerdem gibt er Dir gesprochenes Feedback zu Deinen Trainingsfortschritten.
 
Das optimale Fitnesstraining
Diese Funktion kann auch zusammen mit neuen, in vielen Fitnessstudios vorhandenen Geräten für das Ausdauertraining gekoppelt werden. Suche einfach nach mit Nike + iPod kompatiblen Laufbändern, Elliptical Trainern, Steppern und Hometrainern.
";2;False;0;;;Apple iPod Touch 16 GB;apple-ipod-touch-16-gb-schwarz;True;True;P-1250;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;229.9000;229.9000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39754,6690972222;43;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000141-apple-ipod-touch-16-gb-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000142-apple-ipod-touch-16-gb-schwarz.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000143-apple-ipod-touch-16-gb-schwarz.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Hannspree HL231DPB 58,4 cm (23 Zoll);Hannspree HL231DPB 58,4 cm (23 Zoll) Widescreen LCD Monitor DVI, VGA (Kontrast dyn. 1000:1, 5ms Reaktionszeit) schwarz;Marke: HANNSPREE
Farbe: schwarz (hochglanz)
Produkthöhe: 18.8 cm
Produktbreite: 54.6 cm
Bildschirm Größe: 23 inches
Bildschirm Auflösung: 1920x1080 Pixel
Max. Bildschirmauflösung: 1920 x 1080 pixels
Weitere Spezifikationen
Leistung: 27 Watt
;2;False;0;;;Hannspree HL231DPB 58,4 cm (23 Zoll);hannspree-hl231dpb-584-cm-23-zoll;True;True;P-2540;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;149.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39741,7897800926;"12;2095";26;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000137-hannspree-hl231dpb-584-cm-23-zoll.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000138-hannspree-hl231dpb-584-cm-23-zoll.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000139-hannspree-hl231dpb-584-cm-23-zoll.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Canon PIXMA MP270 Multifunktionsgerät;"Canon PIXMA MP270 Multifunktionsgerät ";"
Canon PIXMA MP270 Multifunktionsgerät
 
 
3 in 1, Drucken, Kopieren, Scannen
 
 
Der PIXMA MP270 ist ein kompaktes, günstiges Multifunktionssystem.
Seine Stärken sind der schnelle Dokumentendruck und der Fotodirektdruck in Laborqualität von PictBridge-kompatiblen Kameras und Fotohandys.
 
Drucken, Kopieren und Scannen
Druckgeschwindigkeit: bis zu 8,4/4,8 ISO-Seiten pro Minute (SW/Farbe)
Bis zu 4.800 dpi Auflösung und 2 Picoliter feine Tintentröpfchen
10 x 15 cm Randlosprint in ca. 45 Sek.
Easy-WebPrint EX
Scanner mit bis zu 1.200 dpi und Auto-Scan-Modus
PictBridge
Selbst öffnendes Papierausgabefach
ChromaLife100+
";2;False;0;;;Canon Pixma MX310 - All in One Drucker - Drucken - Scannen - Kopieren - Faxen;canon-pixma-mp270-multifunktionsgeraet;True;True;P-2210;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;89.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39741,6931365741;22;25;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000132-canon-pixma-mp270-multifunktionsgerat.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"TomTom XL Black Edition Europe Traffic ";"TomTom XL Black Edition Europe Traffic ";"

TomTom XL Black Edition Europe Traffic

TMC ,4,3"" Display, 42 Länderkarten

 
TomTom Navigationsgerät XL Classic Black Edition mit 4,3 Zoll Farb-Touchscreen,
RDS/TMC, 42 vorinstallierten Karten europäischer Länder sowie vielen Innovationen für eine verbesserte und komfortable Navigation
TMC-Empfänger für einen einfachen Zugriff auf Verkehrsinformationen und verschiedene Routenoptionen für die schnellste oder kürzeste Strecke
Mit TomTom HOME und TomTom Map Share das Navi auf dem neusten Stand halten und weitere Features am PC/Mac nutzen
TomTom XL Classic Black Edition in einem edlen schwarzen Gehäuse mit passender EasyPort Halterung für eine einfache Frontscheibenmontage
 
Lieferumfang:
TomTom XL Classic Black Edition, EasyPort-Halterung, USB-Kabel, Autoladegerät, Dokumentation, RDS/TMC-Verkehrsinfo-Empfänger
";2;False;0;;;;tomtom-xl-black-edition-europe-traffic;True;True;P-2000;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;182.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39724,7946643519;66;4;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000131-tomtom-xl-black-edition-europe-traffic.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Western Digital My Passport 320 GB;"Western Digital BAAA3200ABK My Passport Essential 320GB ";"

Western Digital BAAA3200ABK My Passport Essential 320GB  

 
Schnittstellen:1 x Hi-Speed USB, Schnittstellen Typ:Hi-Speed USB, Kapazität:320 GB, Merkmale:
Kennwortauthentifizierung, Details zu Service & Support
Übertragungsrate Schnittstelle:480 Mbit/s, Software inbegriffen:Smartware,
Erforderliches Betriebssystem:Microsoft Windows XP, Microsoft Windows 7, Apple MacOS X 10.4,
Microsoft Windows Vista, Apple MacOS X 10.6, Apple MacOS X 10.5, Stromversorgung:USB-Bus,.
Enthaltene Kabel:1 x USB-Kabel - extern
";2;False;0;;;"Western Digital My Passport 320 GB externe Festplatte ";western-digital-my-passport-320-gb;True;True;P-2590;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;99.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39724,7845023148;14;21;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000130-western-digital-my-passport-320-gb.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Trekstor DataStation maxi g.u 1TB ";"Trekstor DataStation maxi g.u externe Festplatte 1TB ";"

Trekstor DataStation maxi g.u Externe Festplatte 1 TB

 
USB 2.0 inkl. Nero BackItUp 2 Essentials
 
 
Optimale Speicherplatzerweiterung
Die DataStation maxi g.u ist die perfekte Lösung für das
tägliche Backup oder die Speicherplatzerweiterung Ihres PCs.
Die externe 3,5“ Festplatte bietet ausreichend Platz
zum Speichern und Archivieren der heimischen Musik-
und Videosammlung, digitaler Fotos oder anderer Dateien. 
 Schnell und bedienungsfreundlich
Mit dem Hi-Speed USB 2.0 Anschluss bietet die
DataStation maxi g.u einen schnellen Datentransfer.
Die Festplatte ist zudem bereits vorformatiert und
ohne Treiber sofort betriebsbereit.
Unterstützt werden alle gängigen
Dateisysteme von Windows®, Linux® und Mac® OS X,
sowie die Betriebssysteme Microsoft
Windows® 2000 / XP/ Vista, Mac® OS X ab 10.3 und Linux® ab Kernel 2.6.x.
Die Festplatte wird über das mitgelieferte Netzteil mit Strom versorgt. 
Der Ein-/Ausschalter am Festplattengehäuse verhindert überflüssigen Stromverbrauch. 
Exklusives Aluminiumgehäuse
Das exklusive Aluminiumgehäuse der DataStation maxi g.u
sorgt für die optimale Kühlung der Festplatte,
so kommt die externe Festplatte
ohne Lüfter aus und ist leise während des Betriebs 
Inklusive Nero Software „BackItUp2 Essentials“
Die ebenfalls im Lieferumfang enthaltene
Nero Software rundet das Bild der mobilen, externen Festplatte perfekt ab.
Mit Nero BackItUp2 Essentials können Sie Backups Ihrer Daten sehr einfach planen.
So können einzelne Dateien oder ganze Laufwerke gesichert werden.
Um die Datenmenge gering zu halten, komprimiert die Software die Backups direkt „on the fly“.
Auf Wunsch lassen sich die gesicherten Daten auch per Passwortschutz vor unbefugtem Zugriff schützen.
";2;False;0;;;"Trekstor DataStation maxi g.u-externe Festplatte 1 TB ";trekstor-datastation-maxi-gu-1tb;True;True;P-2620;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;129.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39720,7329166667;15;2;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000129-trekstor-datastation-maxi-gu-1tb.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Western Digital My Passport 250 GB ";Western Digital My Passport Essential 250GB;"

Western Digital My Passport Essential 250GB Schwarz

 
Mobiler Hochleistungsspeicher für Ihren Mac® oder PC.
Es ist leicht und robust, einfach zu transportieren und erfordert kein externes Netzteil.
Im Lieferumfang sind eine Software zur Synchronisierung und Verschlüsselung sowie
Google™-Software enthalten.
USB-gesteuert Software zur Synchronisation und Verschlüsselung
Besonders gut tragbare Form
Zum Transportieren von wichtigen Dateien und E-Mails zwischen Büro und Wohnung sowie unterwegs
Gemeinsame Nutzung von großen Dateien zwischen Büro und Wohnung, zwischen PC und Mac.
Kapazität: 250 GB (GigaByte)
maximale Transferrate: 480 Mb/s über USB 2.0
USB 2.0 Anschluss
für PC oder Macintosh Computer
 
Lieferumfang:
Tragbares Festplattenlaufwerk, USB 2.0-Kabel, Schnellinstallationsanleitung
";2;False;0;;;Western Digital My Passport 250 GB 2,5 Zoll Schwarz;western-digital-my-passport-250-gb;True;True;P-2580;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;89.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39707,7523263889;14;21;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000128-western-digital-my-passport-250-gb.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"NAVIGON 4310 max Navigationssystem Europa ";"NAVIGON 4310max Navigationssystem Europa ";"

NAVIGON 4310max Navigationssystem Europa

 
 
40 Länder, inklusive TMC, NAVIGON MyRoutes
 
 
NAVIGON 4310 max Ist nicht nur schön,sondern auch intelligent.
Egal, wo es gerade langgeht, jetzt haben Sie immer eine gute Aussicht: auf die NAVIGON 43 max Serie mit ihrem edlen Design.
Doch die Routenplaner glänzen auch durch innere Werte.
Zum Beispiel empfiehlt Ihnen NAVIGON MyRoutes jederzeit die beste Strecke, zugeschnitten auf Ihren persönlichen Fahrstil, den Wochentag und die Tageszeit.
Für weiteren Komfort sorgen Features wie Reality View Pro, Clever Parking und die TMC-Routeninfo.
 
NAVIGON MyRoutes
Je nachdem, welcher Fahrertyp Sie sind, empfiehlt Ihnen NAVIGON MyRoutes die beste Route – zugeschnitten auf Ihren persönlichen Fahrstil, den Wochentag und die Tageszeit.
Darüber hinaus zeigt Ihnen Ihr NAVIGON bis zu zwei weitere Routen. Das schafft Transparenz. Sie entscheiden, ob Sie unserer Empfehlung folgen oder eine der Alternativen wählen.
 
TMC-Routeninfo
zeigt ihnen im Fall einer Staumeldung eine Alternativroute mit aktualisierter Entfernung und Ankunftszeit.
Sie entscheiden, ob eine Umfahrung in Ihrem Fall sinnvoll ist oder ob Sie die ursprüngliche Route beibehalten wollen.
 
Reality View Pro
zeigt Straßen nicht als Linien, sondern realistisch aus Asphalt und mit Mittelstreifen. So behalten Sie an Autobahnkreuzen und Ausfahrten leichter den Überblick.
 
Clever Parking
hilft Ihnen bei der Parkplatzsuche. Kurz vor Ihrem Ziel zeigt Ihnen Clever Parking Parkplätze in der näheren Umgebung an.
In Deutschland werden Sie sogar über Parkgebühren informiert. So vermeiden Sie langes Suchen und sparen dabei Geld.
 
Lieferumfang:
PNA 4310 max (4,3"" im 16:9 Format) | Kurzanleitung | Halterung Kfz-Ladekabel mit integrierter TMC-Antenne |Vorinstalliertes Kartenmaterial für 40 Länder | USB-Kabel
";2;False;0;;;;navigon-4310-max-navigationssystem-europa;True;True;P-2120;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;199.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39661,6380787037;68;14;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000127-navigon-4310-max-navigationssystem-europa.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Logitech G5 Laser Mouse refresh;"Logitech G5 Laser Mouse refresh ";"
Logitech G5 Laser Mouse refresh
 
 
Kabelgebundene 7-Tasten Tuningmaus mit Laser-Engine
 
 
Spieletaugliche Laser Engine mit 2000 dpi
1.000 Meldungen/Sekunde ermöglichen Präzision bei jeder Geschwindigkeit
Gewichtstuning mit bis zu 38 Gramm
Die Oberfläche mit DryGrip-Technologie beugt müden, verschwitzten Händen vor
Füße aus Polytetrafluorethylen bieten eine besonders gute Gleitfähigkeit der Maus
";2;False;0;;;Logitech G5 Laser Mouse Neu;logitech-g5-laser-mouse-refresh;True;True;P-2770;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;59.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39656,6560300926;21;11;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000124-logitech-g5-laser-mouse-refresh.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Microsoft Bluetooth Mouse 5000 ";"Microsoft Bluetooth Notebook Mouse 5000 ";"
Microsoft Bluetooth Notebook Mouse 5000
 
Bluetooth- und Lasertechnik in Microsoft-Qualität 
 
Mehr Komfort und Sicherheit mit modernen Bluetooth-Notebooks:
Das lästige Empfängermodul für die USB-Schnittstelle entfällt,
die Maus nimmt direkt Kontakt auf mit dem fest eingebauten Bluetooth-Empfänger des Notebooks
Stets informiert: Batteriestandsanzeige auf der Oberseite des Gehäuses (Grün/Rot für Batteriestand OK und niedrig)
Geringe Abmessungen und niedriges Gewicht machen die Maus zum idealen Reisebegleiter.
Bei Nichtverwendung wird die Maus sicher im formschönen Transportcase aufbewahrt
Für Rechts- und Linkshänder geeignetes Gehäuse mit 4 leichtgängigen Maustasten inklusive Scrollrad
Microsoft High Defi nition Laser Technologie für maximale Präzision auch Unterwegs
";2;False;0;;;Microsoft Bluetooth Notebook Mouse 5000;microsoft-bluetooth-mouse-5000;True;True;P-2780;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;49.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39656,6470949074;"21;2095";3;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000123-microsoft-bluetooth-mouse-5000.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Apple iPod shuffle 2 GB pink;Apple iPod shuffle 2 GB pink;"

Apple iPod shuffle 2GB pink
 

 
Wie seine größeren Geschwister besitzt auch der iPod shuffle kreisförmig
angeordnete, ergonomische Bedienelemente.
Der Kopfhöreranschluss am iPod shuffle dient gleichzeitig als Dock-Anschluss.
Drehen Sie den iPod shuffle auf die Seite und setzen Sie ihn in das mitgelieferte Dock ein.
Dank eines stabilen, integrierten Clips lässt sich der iPod shuffle fast überall befestigen.
Klemmen Sie ihn am T-Shirt, am Hemdkragen oder am Trageriemen von Rucksack oder Handtasche fest.
Lassen Sie sich aufs Ungewisse ein: Verwenden Sie den Schalter für die Zufallswiedergabe,
um den Inhalt Ihres iPod shuffle neu zu mischen.
verbesserte Kopfhörer und das neue iTunes 8.0
 
Einfach Musik anhaben mit dem Apple iPOD SHUFFLE 2GB.Tragen Sie bis zu 500 Songs am Ärmel. Oder am Gürtel. Oder am Sportoutfit. Das Erkennungszeichen für Musikfans - den Apple iPOD SHUFFLE. Füllen Sie Ihren Apple iPOD SHUFFLE silber 1GB spielend einfach. iTunes ist der Store für Unterhaltungsinhalte. Ihre super organisierte Musiksammlung und Jukebox. Und die Software, mit der Sie Ihren Apple iPOD SHUFFLE mit einem Mausklick füllen. Das farbige Gehäuse aus eloxiertem Aluminium in silber passt zum genial einfachen Design des Apple iPOD SHUFFLE.
 
Leistungseigenschaften
 
2 GB Flash-Memory Speicher
min. Audio-Datenrate: 8 KBit/s
max. Audio-Datenrate: 320 KBit/s
Frequenzgang-Untergrenze: 20 Hz
Frequenzgang-Obergrenze: 20000 Hz
 
Formate/Standards
 
MP3-Standard
AAC + MP3 Standard
WAV-Dateiformat kompatibel
Audible-Format kompatibel
AIFF-Format kompatibel
 
Bedienung
 
Musiktitel-Verwaltung
 
Leistungsaufnahme/Spannungsversorgung

Li-Polymer Akku
12 Std. Spieldauer mit Akku
Ladezeit für Akku: 4 Std.
 
Anschlüsse
 
Kopfhörer-Anschluß
USB-Schnittstelle
Anschluß für Docking-Station
 
Gehäuse-Eigenschaften
 
Breite: 4.12 cm
Höhe: 2.73 cm
Tiefe: 1.05 cm
Gewicht: 15.5 g

 
";2;False;0;;;Apple iPod shuffle 2 GB pink;apple-ipod-shuffle-2-gb-pink;True;True;P-1130;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;64.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39650,6338888889;37;1;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000118-apple-ipod-shuffle-2-gb-pink.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000119-apple-ipod-shuffle-2-gb-pink.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000120-apple-ipod-shuffle-2-gb-pink.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Me2 ME600HD 500 GB Multimediafestplatte ";"Me2 ME600HD Multimediafestplatte 500 GB ";"

Me2 ME600HD Multimediafestplatte 500 GB

 
 
3,5 Zoll USB 2.0 / Scart / HDMI Multimedia
 
 
Komplett-Lösung für Film- & TV-in Top-Qualität
Direkter Anschluss an das Fernsehgerät zur sofortigen
Wiedergabe von Filmen, Musik oder Fotos -
kein Computer erforderlich 
Mit der Fernbedienung durch die Medien navigieren
Das Bild kann bis zu HDTV-Auflösungen von 1080i skaliert werden -
HDMI, Scart, Component-Video und Digital-Audio Anschlüsse -
Externe USB 2.0 Multimedia Festplatte - Kapazitäten: bis 1000 GB -
High-speed USB 2.0 Externe USB 2.0 Multimedia Festplatte -
Aluminium Gehäuse - Stand-alone Media Player zur Wiedergabe
von MPEG-1, MPEG-2, DivX/Xvid, JPEG, GMC, Qpel, MP3 (ID3 tag),
WAW Media Daten - direkte Wiedergabe von DVD Ordnern - Orderner-Navigation - 
Eigene Playlist benutzen und bearbeiten - einfache Dateiführung, intuitive Bedienung -
unterstützt Progressive Scan (NTSC-480p, PAL-576p)
unterstützt NTFS und FAT32 Dateisysteme geeignet für HDTV (skaliert auf 1080i)
 
Lieferumfang: TV-Infrarotfernbedienung Hi-Speed USB 2.0-Kabel, HDMI-Anschluss
A/V-Kombikabel Component-Kabel Software-CD Bedienungsanleitung
AC Netzteil (100-240V) + Netzkabel
";2;False;0;Me2 ME600HD 500 GB Multimediafestplatte;Me2 ME600HD 500 GB Multimediafestplatte;"Me2 ME600HD 500 GB Multimediafestplatte ";me2-me600hd-500-gb-multimediafestplatte;True;True;P-2660;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;129.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39650,625474537;"16;2095";;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000117-me2-me600hd-500-gb-multimediafestplatte.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Samsung P2450H 24 Zoll HD LCD-Monitor;Samsung P2450H 24 Zoll HD LCD schwarz;"

Samsung P2450H 24 Zoll HD LCD schwarz


HDMI ,Kontrastverhältnis 70000:1, Reaktionszeit 2ms
 

 
Das Modell überzeugt neben dem eleganten ""Touch of Color"" Design auch durch die technischen Features: Neben der VGA- und DVI-D-Schnittstelle bietet das Display auch einen HDMI-Anschluss.
Das sehr hohe dynamische Kontrastverhältnis von 70.000:1 und die Reaktionszeit von 2 ms (G/G) machen den SyncMaster P2450H ebenfalls für Gamer interessant.
Hochwertiges 24"" Display mit Full HD Auflösung und HDMI
Kontrast (dynamisch): 70000:1
Reaktionszeit: 2 ms (G/G)
Lieferumfang: Monitor, Signalkabel, Netzkabel, Treiber CD, Handbuch (CD)
";2;False;0;;;;samsung-p2450h-24-zoll-hd-lcd-monitor;True;True;P-2460;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;2,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;249.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39650,5278472222;9;5;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000114-samsung-p2450h-24-zoll-hd-lcd-monitor.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000115-samsung-p2450h-24-zoll-hd-lcd-monitor.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000116-samsung-p2450h-24-zoll-hd-lcd-monitor.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;Microsoft Windows Vista Home Premium OEM 32 Bit;Microsoft Windows Vista Home Premium OEM 32Bit;"
Mit Windows Vista erledigen Nutzer sicherer und einfacher ihre täglichen Aufgaben und finden sofort, was sie benötigen. Es bietet neue Möglichkeiten für die digitale Unterhaltung und einfachere Kommunikationswege mit anderen Menschen, sowohl zu Hause als auch unterwegs.
Sicherheit und Bedienkomfort standen im Zentrum der Entwicklung von Windows Vista. Nutzer können sich auf die neu gestaltete Bedienoberfläche freuen – im neuen Look and Feel. Außerdem kümmert sich Vista noch mehr darum, Ordnung in die Datenflut auf der Festplatte zu bringen. Es wird leichter, Dokumente zu finden oder Multimedia-Daten zu verwalten und zu nutzen.
 
Neue Benutzeroberfläche
Windows Vista vereinfacht deutlich das Arbeiten mit dem PC. So sorgt eine benutzerfreundliche Oberfläche dafür, dass der Anwender jederzeit sofort auf die gewünschten Daten zugreifen kann. Integrierte, systemweite Suchfunktionen vereinfachen das Speichern, Auffinden, Verwalten und Organisieren wichtiger Dateien und Programme.
 
Damit bleiben E-Mails, Dokumente, Bilder, Videos, Musik, Spiele und Websites immer im Griff. Bei der Suche auf dem Desktop-PC braucht der Nutzer nicht mehr den Namen einer Datei zu kennen, es reicht ein Wort im Dokument, der Musikinterpret oder das Datum der Fotografie, um sie zu finden.
 
 
Das neue Vista Start-Menü mit integrierter Schnellsuche 
 
Mit „Flip“ lässt sich von einem geöffneten Fenster komfortabel zum nächsten wechseln, wobei für jedes Fenster eine Live-Miniaturansicht angezeigt wird. Mit Hilfe der Miniaturansichten kann der Nutzer das gewünschte Fenster schnell ermitteln, insbesondere wenn mehrere Fenster desselben Typs geöffnet sind. „Flip 3D“ ermöglicht das Verwenden des Bildlaufrads der Maus zum Sichten mehrerer geöffneter Fenster und anschließenden Auswählen des gewünschten Fensters.
 
Damit Informationen nur einen Mausklick entfernt sind, bietet Windows Vista Minianwendungen. Diese verbinden sich mit Web Services zur Wiedergabe von ständig aktualisierten Informationsdiensten wie Wetterberichte, Nachrichten oder Internet-Radio-Programme. Sie können auch alle Instant-Messaging-Kontakte und Tagesaufgaben anzeigen sowie als Taschenrechner oder Notizzettel fungieren. Alle Minianwendungen werden über die am rechten Bildschirmrand befindliche Windows Sidebar organisiert und aufgerufen.
 
Windows Aero
Windows Vista ist das erste Windows-Betriebssystem mit einer Benutzerumgebung, die mühelos an die Hardwaremöglichkeiten des Computers angepasst werden kann, auf dem sie installiert ist. Auf allen Computern, welche die Mindestanforderungen an die Hardware erfüllen, wird die Basisbenutzerumgebung von Windows Vista angezeigt, in der Sie die bereits erwähnten optimierten Oberflächenfunktionen finden.
 
Windows Aero ist eine Umgebung mit einem zusätzlichen Grad an visueller Ausgereiftheit, die reaktionsschneller und verwaltbarer ist und Windows-Benutzern mehr Übersichtlichkeit und Benutzerfreundlichkeit bietet.
 
 
Windows Vista Aero bietet spektakuläre visuelle Effekte, wie zum Beispiel transparente Bedienelemente 
 
Jederzeit verbunden
Windows Vista-basierte Heimcomputer, Laptops oder Tablet-PCs sind nach dem Einschalten so schnell einsatzbereit wie herkömmliche Elektronikgeräte und lassen sich auch genauso schnell ausschalten. Damit können Privatnutzer sofort auf ihre Anwendungen zugreifen, im Internet surfen oder mit ihren Freunden und Bekannten kommunizieren.
 
Mit dem neuen „Ruhezustand“ von Windows Vista dauert trotz niedrigen Stromverbrauchs die Reaktivierung des PCs nur zwei bis drei Sekunden. Dadurch braucht der Anwender seinen Computer weniger häufig herunterfahren und neu starten. Außerdem passt das Betriebssystem seine Leistung automatisch an verschiedene Nutzer an, indem es die jeweils am häufigsten genutzten Anwendungen bereits vor dem Aufruf lädt.
 
 
Die Windows Sidebar bietet schnellen Zugriff auf Minianwendungen, wie etwa Wetterberichte oder Nachrichten 
 
Über das Windows Synchronisierungscenter gleicht er die Inhalte tragbarer Geräte wie Telefone, PDAs und Musik-Player mit PCs ab. Über das Windows Mobilitätscenter kann er sogar auf Einstellungen mobiler Computer zugreifen und diese ändern.
 
Plattform für Digitale Unterhaltung
Windows Vista enthält ein Media Center mit Zugriff per Fernbedienung auf alle wichtigen Unterhaltungsmöglichkeiten wie Musik, Bilder, Filme, TV, aufgezeichnete Sendungen und Services. Da die Software HD TV und HD DVD unterstützt, wurde die Oberfläche für High-Definiton (HD) Breitwand-Bildschirme optimiert und überarbeitet. Sie bietet eine einfache und übersichtliche Suche nach allen digitalen Medien. Das Media Center lässt sich über die Media Center Extender-Funktionalität der Xbox 360 auf das gesamte Heim erweitern.
 
Microsoft treibt gemeinsam mit Intel und AMD die weitere Entwicklung des digitalen Heims voran. Die Intel Viiv-Technologie bietet eine neue Plattform für digitale Unterhaltung, die leistungsstarke Dual-Core-Prozessoren nutzt. AMD bietet AMD Live! auf Multimedia-Desktop-PCs und -Notebooks an, die rechtzeitig zum Erscheinen von Windows Vista auf den Markt kommen.
 
 
Mit Flip und Flip 3D navigiert man dank übersichtlicher Miniaturansichten mühelos durch die geöffneten Fenster 
 
Musik, Bilder und Spiele
Der in Windows Vista integrierte Media Player 11 enthält eine aufgefrischte Oberfläche mit neuen Navigationsmöglichkeiten. Damit durchsuchen Musikfans noch schneller und effizienter ihre Sammlungen: Während der Eingabe zeigt der Media Player 11 sofort eine aktualisierte Auswahl möglicher Begriffe an.
 
Mit der Windows Fotogalerie können Nutzer ihre Fotos und Videos von Digitalkameras miteinander tauschen und ansehen. Sie vereinfacht die Verwaltung von Bildern und enthält grundlegende Schneide- und Korrekturfunktionen. Für das Importieren, Schneiden und Organisieren von Videos steht der Windows Movie Maker zur Verfügung.
 
Die persönlichen Lieblingsspiele lassen sich über den Games Explorer einfacher aufrufen. Die aktuelle Version der Programmier-Schnittstelle DirectX 10 bietet größeren Detailreichtum und mehr Tiefenschärfe bei Spielegrafiken sowie eine fünffach höhere Leistungsfähigkeit. Außerdem stehen viele neue und überarbeitete Games zur Verfügung wie „Halo 2 für Windows Vista“, „Flight Simulator X“ und „Mahjong-Giganten“.
 
 
Über das Windows Media Center lassen sich Fernsehprogramme, Filme, Musik und Bilder bequem per Fernbedienung steuern 
 
Sicherheit und Jugendschutz
Das neue Sicherheitskonzept von Windows Vista hat zu zahlreichen Innovationen geführt. So schützt der Windows Defender den PC vor aktuellen Gefahren wie Würmer, Viren und Spyware. Der integrierte Internet Explorer 7 verhindert unter anderem Schäden durch gefälschte Websites und E-Mails.
 
Der neue Benutzerkontoschutz unterscheidet Standardaktivitäten von besonders kritischen Aktionen. Standardaktivitäten wie das Surfen im Web, das Senden von E-Mails oder das Verwenden von Office-Programmen sind wenig sicherheitskritisch und erfordern daher keine besonderen Berechtigungen. Wenn der Anwender jedoch eine kritische Aktion durchführen will, zum Beispiel die Installation eines neuen Programms, fordert Windows Vista die Eingabe eines eigenen Kennworts. Dadurch wird es für bösartige Programme schwieriger, den PC zu befallen.
 
Außerdem verhindert der Benutzerkontoschutz, dass PC-unerfahrene Familienmitglieder unbeabsichtigt sicherheitskritische Aktionen durchführen oder heruntergeladene Programme installieren. Mit speziellen Sicherheitseinstellungen in Windows Vista können Eltern zudem die Computernutzung ihrer Kinder kontrollieren.
 
Komfortabler Surfen
Internet Explorer 7 bietet nicht nur wichtige neue Sicherheits- und Datenschutzfeatures, sondern erleichtert auch gängige Aufgaben durch Features wie Registernavigation (Anzeige von Fenstern im Registerkartenformat), Onlinesuche und an die Blattgröße angepasste Druckvorgänge.
 
Gleichzeitig werden neue Tools bereitgestellt, um einen direkten Zugriff auf die gewünschten Informationen zu ermöglichen, mit integrierter Unterstützung von Webfeeds (auch als RSS oder Really Simple Syndication bezeichnet). RSS ist eine Technologie zum Abonnieren von Informationen, damit Sie nicht nach diesen suchen müssen. Über RSS-Abonnements erhalten Sie automatisch Listen (Feeds) von Überschriften aus Websites.
 
Internet Explorer erkennt diese Feeds zu Websites und ermöglicht, diese in einer Vorschau anzuzeigen und zu abonnieren. Nach der Abonnierung fasst Internet Explorer 7 Überschriften in jedem Feed automatisch in einer Liste zusammen. Dadurch können Sie neue Informationen auf verschiedenen Websites schnell durchsuchen, ohne die Websites einzeln besuchen zu müssen.
 
Features:
 
Ideal für private Anwender, begeisterte Mediennutzer, mobile Anwender und Familien
Die neue Oberfläche Windows Aero sorgt für mehr Übersichtlichkeit und Benutzerfreundlichkeit
Leistungsstarke integrierte Desktopsuchfunktionen, mit denen nahezu alles auf dem PC schnell gefunden werden kann
Unterstützt Minianwendungen, die sich mit Webdiensten verbinden, um Wetterberichte, aktualisierte Nachrichten, Straßenkarten oder Internetradio bereitzustellen
Schnelles und gezieltes Wechseln zwischen verschiedenen Fenstern mit Hilfe von Windows Flip 3D
Unterstützung neuester Spiele-Technologie durch DirectX 10
Windows Media Center bietet Zugriff auf Live- und aufgezeichnete Fernsehprogramme, Filme, Musik und Bilder - über Media Center-Erweiterungen sogar überall im Haus
Enthält Windows Media Player 11, die digitale Musiksoftware der nächsten Generation
Windows Defender schützt vor Spyware, Viren und Würmern
Der neue Benutzerkontoschutz verbindet die Flexibilität eines Administratorkontos mit der Sicherheit eines Benutzerkontos
Mehr Sicherheit und Komfort beim Surfen mit dem neuen Internet Explorer 7
Reaktivierung des PCs aus dem Ruhezustand in nur 2 bis 3 Sekunden
Unterstützt leistungsstarke Dual-Core-Systeme
";2;False;0;;;" Windows Vista Home Premium 32 Bit OEM ";microsoft-windows-vista-home-premium-oem-32-bit;True;True;P-2970;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;49.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39650,5243865741;"80;30;2095";3;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000109-microsoft-windows-vista-home-premium-oem-32-bit.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000110-microsoft-windows-vista-home-premium-oem-32-bit.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000111-microsoft-windows-vista-home-premium-oem-32-bit.jpg;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"Garmin Topo Österreich V2 ";"Garmin Topo Österreich V2 ";"

Garmin Topo  Österreich V2

 
Digitale topographische Vektorkarte-Originallizenz
 
 
Topo Österreich ist die perfekte Ergänzung für Ihr Garmin GPS!
Die neueste Version der beliebten Outdoor-Karte ist auf allen kartenfähigen Garmin GPS-Geräten lauffähig.
Die Topo Österreich bietet eine Vielzahl an Informationen wie Wanderwege, Straßen, Seen, Flüsse, Wälder,
Berggipfel sowie Höhenlinien im Abstand von 20m und mehr als 800 gespeicherte Positionen von Schutzhütten.
Die neue Topo Österreich ist mit einem digitalen Höhenmodell hinterlegt und erstmals auch routingfähig!
Planen Sie Ihre Touren, Routen und Wegpunkte am PC oder direkt am GPS-Gerät -
die Topo Österreich ist die perfekte Kartengrundlage für Wanderungen und Touren abseits der Straße!Tausende Points of Interest (Gasthäuser, Hotels, Parkplätze, Gemeindeämter ...)
Suchmöglichkeiten für Geonamen, POIs und Städte/Orte.
Auch abseits von Straßen auf Wegen und Pfaden routingfähig, sie folgt beim Anlegen von Routen automatisch den auf der Karte verzeichneten Wegen, was die Navigation deutlich vereinfacht
Dank der mitgelieferten MicroSD-Karte ist die Handhabung der Topo Österreich V2 sehr einfach:
MicroSD-Karte in Garmin Navigationsgerät einlegen ¿ fertig. Eine Onlinefreischaltung ist für die Nutzung mit MicroSD-Karte nicht erforderlich.
Höhenlinien im Abstand von 20m, mit anschaulicher Geländedarstellung
Komfortable Routen- & Wegpunktverwaltung
Einfache Übertragen von Wegpunkten, Routen & Tracks auf Garmin GPS Geräte
Gesamtdatenvolumen ca. 175 MB. Die Karte ist in 196 einzelne Kartenabschnitte unterteilt,
die zwischen 100 kB und 1,6 MB groß sind.
Lizenz zur Freischaltung eines Gerätes. Registrierung über Internet erforderlich.
Digitale topographische Vektorkarte Routenplanung: MapSource-Produkt -
die Kartendaten werden mit der Software MapSource bearbeitet.
";2;False;0;;;Garmin Topo CD Österreich;garmin-topo-oesterreich-v2;True;True;P-2030;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;189.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39650,5216550926;"67;2095";44;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000108-garmin-topo-osterreich-v2.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"TomTom ONE Europe Classic Edition TMC ";"TomTom ONE Europe Classic Edition TMC ";"

TomTom ONE Europe Classic Edition TMC 
 

TomTom ONE Classic Europe 42 Traffic mit RDS/TMC-Empfänger

 

Der neue ONE Classic Europe 42 Traffic mit EasyPort passt mit Saugnapfhalterung in jede Hemdtasche.
Ein 3,5-Zoll-Touchscreen, hervorragende Sprachqualität, TMC zur Stauumfahrung, TomTom Map Share, Hilfe!-Menü für Notfälle 
für die neueste Kartenversion und Kartenmaterial von West- und Osteuropa (42 Länder) machen dieses TomTom ONE Classic so einzigartig.
TomTom ONE Classic Europe 42 Traffic mit 3,5 Zoll Touchscreen, USB-Heimladegerät, einem RDS/TMC-Empfänger und QuickGPSfix-Funktion für eine sekundenschnelle Navigationsbereitschaft
vorinstalliertes Kartenmaterial von 32 Ländern aus Ost- und Westeuropa mit Kartenaktualisierung und eigener Kartenanpassung über TomTom HOME und Map Share
Navigieren von Haustür zu Haustür mit Details zu Adressen, Hausnummern, Tankstellen sowie Orten von besonderem Interesse (Points of Interest, POI), 3D- / 2D-Ansicht mit Tages- und Nachtansichtmodus
RDS/TMC-Verkehrsinfo-Empfänger für aktuelle Staumeldungen und Verkehrshinweise zum Umfahren schwieriger Verkehrssituationen und alternative Routen
Lieferumfang: TomTom One Classic Europe 42 Traffic, EasyPort-Halterung, USB-Kabel, Autoladegerät, Dokumentation, RDS/TMC-Empfänger
";2;False;0;;;;tomtom-one-europe-classic-edition-tmc;True;True;P-1990;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;130.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39650,5188541667;66;4;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000107-tomtom-one-europe-classic-edition-tmc.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;0;True;"TomTom Go 740 Live Navigationssystem ";"TomTom Go 740 Live Navigationssystem schwarz ";"
TomTom Go 740 Live Navigationssystem  schwarz
 
4,3 Zoll Touchscreen, 32+10 Länderkarten, TMC, Bluetooth

GO 740 LIVE mit 4,3 Zoll Farb-Touchscreen, 42 vorinstallierten Karten europäischer Länder (davon 10 Hauptverkehrsstraßen-Karten), Bluetooth,
Kfz-Freisprecheinrichtung sowie vielen Innovationen für eine verbesserte und komfortable Navigation
Sprachsteuerung, LIVE Services mit HD Traffic, Sicherheitswarnungen, Lokale Suche mit Google, Wetter, QuickGPSfix sowie Fahrspurassistent für komplizierte Spurenführungen
IQ Routes - Intelligente Routenberechnung aus aktuellsten Karten unter Berücksichtigung verschiedener Umweltfaktoren wie Tag, Uhrzeit, Straßenabschnitt, Durchschnittsgeschwindigkeiten etc.
Text-to-Speech zum Ansagen von Straßennamen und Verkehrshinweisen für einen konzentrierten Blick auf die Fahrbahn und ein entspanntes Fahren
Lieferumfang: TomTom GO 740 LIVE,Active-Dock Kfz-Halterung, Dockinghalterung für PC/Mac, Autoladegerät, Benutzerhandbuch, CD-ROM (TomTom HOME-Software)
";2;False;0;;;;tomtom-go-740-live-navigationssystem;True;True;P-1980;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;249.9000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;39650,5165162037;66;4;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000106-tomtom-go-740-live-navigationssystem.jpg;;;2;;False;;;;;False;False;False;;;;;False;;;;;; -5;210;True;SmartStore Office;;"

Der Marketing- und Verkaufsmanager für ein erfolgreiches Online-Business

Kunden gewinnen, Kunden binden, Umsatz steigern


SmartStore Office ist die leistungsstarke Software-Lösung zur Steuerung Ihrer Online-Verkaufs- und Marketings-Aktivitäten. Auf bahnbrechend einfache und intelligente Weise ermöglicht sie:

 

 

  • Die Planung und Durchführung hocheffektiver Email-Marketing-Kampagnen zur Neukundengewinnung
  • Die Verwaltung und Abwicklung von Bestellungen für störungsfreie Abläufe in Ihrem BackOffice
  • Die rasche Umsetzung von Maßnahmen zur Kundenbindung
  • Eine wirksame Optimierung Ihres Online-Angebotes dank umfangreicher statistischer Auswertungen

SmartStore Office bietet eine hochmoderne und -intuitive Bedienerführung, die den Aufbau und das Organisieren des "perfekten" Online-Business zu einem Kinderspiel macht. Im SmartStore-typischen Point&Click-Verfahren können Sie auf einfachste Weise:

 

 

  • Professionelle HTML-Newsletter und Serien-Emails erstellen und an tausende Kontakte gleichzeitig versenden
  • Ihre Kunden, Interessenten, Partner und Mitglieder mit den neuesten Informationen rund um Ihr Angebot versorgen
  • Ihre Top-(Produkt)-Angebote mitsamt Abbildungen, Beschreibungen und Preisen mit einem Klick in Ihre Emailings integrieren
  • Den Inhalt Ihrer Emailings personalisieren
  • View- und Klick-Raten Ihrer Emailings auswerten
  • Durch gezielte Nachfassaktionen Folge-Geschäfte generieren
  • Ihre Online-Bestellungen abrufen und bearbeiten
  • Rechnungen, Lieferscheine und sonstige Berichte drucken oder direkt als Emails an Ihren Kunden senden

SmartStore Office ist die unverzichtbare Ergänzung zu unserer marktführenden und mehrfach ausgezeichneten Ecommerce-Komplettlösung SmartStore.biz. Die einzigartige Interaktion zwischen beiden Anwendungen erhöht die Erfolgsrate Ihres Online-Business erheblich:

  • Kunden, Interessenten und Newsletter-Abonnenten werden in einer zentralen Datenbank gespeichert. Sie verfügen dadurch automatisch über "reiche" Kontaktdaten, die absolut zielgerichtete und hocheffektive Email-Personalisierung ermöglichen.
  • Produkt-Informationen aus einem bestehenden SmartStore.biz Produktkatalog lassen sich automatisch in ein Emailing einfügen. Dabei kann jedes Produkt mit den Produkt-Detail-Informationen in Ihrem Online-Shop verlinkt werden.
  • Aussagefähige Auswertungen zu Newslettern, Kunden, Produkten, Umsätzen etc. geben Ihnen wertvolle Hinweise zur weitergehenden Optimierung Ihres Angebotes. Sie können bspw. das Klick-Verhalten Ihrer Leser auswerten, und so wertvolle Erkentnisse über evtl. geplante Nachfassaktionen gewinnen.
  • Keine Reibungsverluste, keine Insellösungen, keine lästige "Datenschieberei" mehr von Anwendung A nach B!
";2;False;0;;;SmartStore Office;smartstore-office;True;True;P-2950;;;False;0;False;;False;False;0;False;0;1;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;2;10000;False;False;5;1;1;0;False;1;10000;;False;False;False;False;99.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;38938,5373611111;"2095;81";42;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000095-smartstore-office.gif;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000096-smartstore-office.gif;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000097-smartstore-office.gif;1;;True;kg;2.0000;1;;False;False;False;;;;;False;;;;;; -5;210;True;SmartStore eBay SmartSeller;;"

Der clevere Verkaufsmanager für eBay!


eBay SmartSeller ist eine eCommerce-Anwendung, mit der Sie Ihre Produkte auf einfache und bequeme Weise auf dem Online-Marktplatz von eBay anbieten können. Verschiedene Module wie Kundenverwaltung, Fakturierung oder Nachrichten-Manager unterstützen Sie bei der Abwicklung verkaufter Produkte und übernehmen Aufgaben, die Sie sonst manuell erledigen müssten.

Direkter Zugang

eBay SmartSeller ermöglicht Ihnen einen direkten Zugang zum größten Online-Marktplatz der Welt, ohne langwieriges Mausklicken oder Suchen. Profitieren Sie von den allerneuesten eBay-Technologien; vereint in einer - durch eBay zertifizierten - Anwendung.

Kosten minimieren

Minimieren Sie Ihre Kosten, die Ihnen rund um Ihre eBay-Geschäfte entstehen. Mit eBay SmartSeller ist ein für alle mal Schluss mit versteckten oder zusätzlichen Kosten. Keine Drittanbieter, die an Ihren Umsätzen partizipieren. eBay berechnet Ihnen lediglich die allgemein üblichen Gebühren fürs Einstellen einer Auktion und die Provision, die bei einem erfolgreichen Abschluss anfällt. Über den eBay SmartSeller sind diese Gebühren voll transparent und zu jedem Zeitpunkt durch Sie nachvollziehbar.

Auktionen verwalten

Legen Sie beliebig viele Artikel an, wahlweise mit oder ohne Assistenten. Die Ordneransicht hilft Ihnen dabei, die Artikel zu ordnen, um selbst bei einer großen Artikelanzahl nicht den Überblick zu verlieren.

Starten Sie eine beliebige Anzahl von Auktionen, Festpreisverkäufen oder eBay-Shop-Einträgen. Der Clou dabei: Die Listings erscheinen im Datengitter schräg unterhalb Ihrer Artikel, d.h. Sie können ganz genau den Verlauf Ihrer Artikel über den Lebenszyklus von eBay-Auktionen hinweg mitverfolgen. Zusätzlich gewährleistet der Auktionsstatus, dass Sie stets den Überblick über Ihre eBay-Verkaufsaktivitäten behalten und sofort wissen, wann neue Auktionen gestartet werden müssen.

Zeitsparend abwickeln

eBay SmartSeller verfügt über eine umfangreiche Kundenverwaltung, in der Kunden und deren Rechnungen hierarchisch und übersichtlich präsentiert werden. Mit dem Rechnungsassistenten lassen sich komfortabel Rechnungen erstellen, drucken und betrachten. Und mit dem Mahnungsassistenten benachrichtigen Sie mit wenigen Klicks säumige Käufer. Darüber hinaus ermöglicht der Bewertungs-Manager die zügige Bewertungs-Abgabe: wahlweise für ausgewählte oder alle noch nicht bewerteten Transaktionen.

Professionelle Auktionsvorlagen

Im eBay SmartSeller integriert ist ein vollwertiger HTML-Editor, mit dem Sie das Aussehen Ihrer Auktionen gestalten können. Oder nutzen Sie einfach die mitgelieferten HTML-Vorlagen, die speziell für die Gestaltung von Auktionen entwickelt und auf das Kategorie-Angebot von eBay abgestimmt wurden. Einer professionellen Präsentation Ihrer Produkte und höherer Erfolgschancen Ihrer Auktionen stehen hier nichts mehr im Wege.

Beobachten und Bieten

Zum Beobachten und Bieten von Auktionen steht eine separates Modul zur Verfügung, über das individuelle Suchanfragen erstellt werden können. So filtern Sie gezielt alle für Sie relevanten Angebote aus dem Gesamtangebot bei eBay heraus und behalten die Übersicht über den Online-Marktplatz.

SmartStore.biz und SmartStore Office enabled

eBay SmartSeller kommuniziert reibungslos mit dem Shopsystem SmartStore.biz und dem Marketing- und Verkaufs-Manager SmartStore Office: Mit wenigen Klicks lassen sich in SmartStore.biz bereits erfasste Artikel-Daten übernehmen; ebenso einfach lassen sich Kunden und Bestellungen zur weiteren Abwicklung nach SmartStore Office übergeben. ";2;False;0;;;SmartStore eBay SmartSeller;smartstore-ebay-smartseller;True;False;P-2940;;;False;0;False;;False;False;0;False;0;0;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;0;10000;False;False;0;1;1;0;False;1;10000;;False;False;False;False;79.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;38938,5365625;"29;2095;81";42;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000090-smartstore-ebay-smartseller.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000091-smartstore-ebay-smartseller.gif;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000092-smartstore-ebay-smartseller.gif;1;;False;;;;;False;False;False;;;;;False;;;;;; -5;210;True;SmartStore.biz 5;;"
Achtung, Fertig, Klick!
Das Mega-Update SmartStore.biz 5

Es ist soweit! Mit SmartStore.biz 5 geht eine Revolution im Bereich Desktop- basierender Online-Shop-Systeme an den Start.

Alles ist neu, besser, größer, einfacher!

SmartStore.biz ist in der Version 5 komplett neu entwickelt worden. Dabei wurden bewährte Programmabschnitte ausgebaut, viele bahnbrechend neue Funktionen implementiert und verbesserte Bedienungsabläufe ausgearbeitet. Nie zuvor war es so einfach, einen hochwertigen und modernen Online-Shop zu gestalten und zu organisieren.

SmartStore.biz 5 bietet für das individuelle Erscheinungsbild eines Online-Shops unzählige Variationen im Bereich Layout & Design, eine schnelle und unkomplizierte Produktverwaltung und darüber hinaus ein herausragendes Content-Management.

Eines der größten Highlights ist das integrierte WYSIWYG-Redaktionssystem mit nahezu unbegrenzten Möglichkeiten, den eigenen Online-Shop inhaltlich zu gestalten. Hand in Hand mit dem neuen Designer und einer Auswahl mitgelieferter Designvorlagen verleihen Sie Ihrem Shop per Klick ein höchst anspruchsvolles Look & Feel.

Nahtlos in die inhaltliche Gestaltung eingebunden ist auch der stark ausgebaute Produktmanager. Auf einfachste Weise sorgt das Zusammenspiel beider Bereiche für eine perfekte Produktpräsentation und ist die optimale Voraussetzung für einen erfolgreichen Online-Shop.

SmartStore.biz 5 ist von Haus bereits optimal für Suchmaschinen optimiert und erstellt für die maximale Präsenz zudem Webpfade aus lesbaren und völlig frei konfigurierbaren Namen für Verzeichnisse und Dateien. Die aussagekräftigen Linkpfade unterstützen dabei auch den Besucher der Seiten bei seiner Navigation durch den Katalog.

";2;False;0;;;SmartStore.Biz 5;smartstorebiz-5;True;True;P-2930;;;False;0;False;169;True;False;0;False;0;1;False;;False;;False;0;0;0;True;False;0,0000;False;False;1;1;10000;False;True;1;1;1;0;False;1;10000;;False;False;False;False;149.0000;0.0000;0.0000;;0.0;0.0;False;0.0000;0.0000;0.0000;0.0000;0.0000;0.0000;38938,536400463;"29;81;2095";42;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000088-smartstorebiz-5.jpg;D:\Develop\Git\smartstorenetfull\SmartStoreNET\src\Presentation\SmartStore.Web\Media\Thumbs\0000\0000089-smartstorebiz-5.png;;1;;False;ounce;;;;False;False;False;;;;;False;;;;;; From 8619c2eced34aa26f3c35e327e7634f231b9f74f Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Thu, 10 Dec 2015 20:13:29 +0100 Subject: [PATCH 075/626] Editing an import profile --- .../DataExchange/ExportProfileService.cs | 4 + .../Import/ImportProfileService.cs | 12 ++- .../Controllers/ImportController.cs | 88 ++++++++++++++----- .../Models/DataExchange/ImportProfileModel.cs | 2 +- .../Administration/SmartStore.Admin.csproj | 2 + .../Administration/Views/Export/List.cshtml | 7 -- .../Administration/Views/Import/Edit.cshtml | 37 ++++++++ .../Administration/Views/Import/List.cshtml | 8 +- .../Views/Import/_CreateOrUpdate.cshtml | 45 +++++++++- .../Views/Import/_ImportFileList.cshtml | 35 ++++++++ 10 files changed, 207 insertions(+), 33 deletions(-) create mode 100644 src/Presentation/SmartStore.Web/Administration/Views/Import/Edit.cshtml create mode 100644 src/Presentation/SmartStore.Web/Administration/Views/Import/_ImportFileList.cshtml diff --git a/src/Libraries/SmartStore.Services/DataExchange/ExportProfileService.cs b/src/Libraries/SmartStore.Services/DataExchange/ExportProfileService.cs index 53776a31c7..948b1d8ded 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/ExportProfileService.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/ExportProfileService.cs @@ -210,6 +210,10 @@ public virtual void UpdateExportProfile(ExportProfile profile) if (profile == null) throw new ArgumentNullException("profile"); + profile.FolderName = profile.FolderName + .ToValidPath() + .Truncate(_dataExchangeSettings.MaxFileNameLength); + _exportProfileRepository.Update(profile); _eventPublisher.EntityUpdated(profile); diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportProfileService.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportProfileService.cs index 21bbb22823..dce39f68d6 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportProfileService.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportProfileService.cs @@ -73,6 +73,10 @@ public virtual void UpdateImportProfile(ImportProfile profile) if (profile == null) throw new ArgumentNullException("profile"); + profile.FolderName = profile.FolderName + .ToValidPath() + .Truncate(_dataExchangeSettings.MaxFileNameLength); + _importProfileRepository.Update(profile); _eventPublisher.EntityUpdated(profile); @@ -83,7 +87,8 @@ public virtual void DeleteImportProfile(ImportProfile profile) if (profile == null) throw new ArgumentNullException("profile"); - int scheduleTaskId = profile.SchedulingTaskId; + var scheduleTaskId = profile.SchedulingTaskId; + var folder = profile.GetImportFolder(); _importProfileRepository.Delete(profile); @@ -91,6 +96,11 @@ public virtual void DeleteImportProfile(ImportProfile profile) _scheduleTaskService.DeleteTask(scheduleTask); _eventPublisher.EntityDeleted(profile); + + if (System.IO.Directory.Exists(folder)) + { + FileSystemHelper.ClearDirectory(folder, true); + } } public virtual IQueryable GetImportProfiles(bool? enabled = null) diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs index 4cf43afe3f..57997043c6 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs @@ -65,8 +65,13 @@ private void PrepareProfileModel(ImportProfileModel model, ImportProfile profile model.ExistingFileNames = profile.GetImportFiles() .Select(x => Path.GetFileName(x)) + .OrderBy(x => x) .ToList(); } + else + { + model.ExistingFileNames = new List(); + } if (forEdit) { @@ -115,12 +120,14 @@ public ActionResult Create() } [HttpPost, ParameterBasedOnFormName("save-continue", "continueEditing"), FormValueRequired("save", "save-continue")] - public ActionResult Create(ImportProfileModel model, ImportEntityType entityType) + public ActionResult Create(ImportProfileModel model) { if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageImports)) return AccessDeniedView(); - if (!System.IO.File.Exists(model.TempImportFile)) + string[] tempFiles = model.TempImportFiles.SplitSafe("|"); + + if (tempFiles.Length == 0) { ModelState.AddModelError("ImportFiles", T("Admin.DataExchange.Import.MissingImportFile")); } @@ -131,9 +138,12 @@ public ActionResult Create(ImportProfileModel model, ImportEntityType entityType if (profile != null && profile.Id != 0) { var folder = profile.GetImportFolder(true, true); - var destPath = Path.Combine(folder, Path.GetFileName(model.TempImportFile)); + var tempDir = FileSystemHelper.TempDir(); - FileSystemHelper.Copy(model.TempImportFile, destPath, true, true); + foreach (var file in tempFiles) + { + FileSystemHelper.Copy(Path.Combine(tempDir, file), Path.Combine(folder, file), true, true); + } return RedirectToAction("Edit", new { id = profile.Id }); } @@ -178,8 +188,11 @@ public ActionResult Edit(ImportProfileModel model, bool continueEditing) profile.Name = model.Name; profile.FolderName = model.FolderName; + profile.EntityType = model.EntityType; profile.Enabled = model.Enabled; - + profile.Skip = model.Skip; + profile.Take = model.Take; + profile.Cleanup = model.Cleanup; _importService.UpdateImportProfile(profile); @@ -218,8 +231,8 @@ public ActionResult DeleteConfirmed(int id) public JsonResult FileUpload(int id) { var success = false; - string error = null; - string tempFile = null; + string tempFile = ""; + string fileList = ""; if (_services.Permissions.Authorize(StandardPermissionProvider.ManageImports)) { @@ -228,28 +241,44 @@ public JsonResult FileUpload(int id) { if (id == 0) { - tempFile = Path.Combine(FileSystemHelper.TempDir(), postedFile.FileName); - FileSystemHelper.Delete(tempFile); + var path = Path.Combine(FileSystemHelper.TempDir(), postedFile.FileName); + FileSystemHelper.Delete(path); + + success = postedFile.Stream.ToFile(path); + + if (success) + tempFile = postedFile.FileName; } else { + var profile = _importService.GetImportProfileById(id); + if (profile != null) + { + var folder = profile.GetImportFolder(true, true); + var destFile = Path.Combine(folder, Path.GetFileName(postedFile.FileName)); + + success = postedFile.Stream.ToFile(destFile); + + if (success) + { + var model = new ImportProfileModel(); + PrepareProfileModel(model, profile, false); + + fileList = this.RenderPartialViewToString("_ImportFileList", model); + } + } } - - success = postedFile.Stream.ToFile(tempFile); - - if (!success) - error = T("Admin.Common.UploadFileFailed"); } + + if (!success) + NotifyError(T("Admin.Common.UploadFileFailed")); } else { - error = T("Admin.AccessDenied.Description"); + NotifyError(T("Admin.AccessDenied.Description")); } - if (error.HasValue()) - NotifyError(error, true); - - return Json(new { success = success, tempFile = tempFile }); + return Json(new { success = success, tempFile = tempFile, fileList = fileList }); } [HttpPost] @@ -287,7 +316,7 @@ public ActionResult DownloadLogFile(int id) return result; } - public ActionResult DownloadExportFile(int id, string name) + public ActionResult DownloadImportFile(int id, string name) { if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageImports)) return AccessDeniedView(); @@ -308,5 +337,24 @@ public ActionResult DownloadExportFile(int id, string name) return result; } + + public ActionResult DeleteImportFile(int id, string name) + { + if (_services.Permissions.Authorize(StandardPermissionProvider.ManageImports)) + { + var profile = _importService.GetImportProfileById(id); + if (profile != null) + { + var path = Path.Combine(profile.GetImportFolder(true), name); + FileSystemHelper.Delete(path); + + var model = new ImportProfileModel(); + PrepareProfileModel(model, profile, false); + + return PartialView("_ImportFileList", model); + } + } + return new EmptyResult(); + } } } \ No newline at end of file diff --git a/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ImportProfileModel.cs b/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ImportProfileModel.cs index 77bb5f64ea..11724f7622 100644 --- a/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ImportProfileModel.cs +++ b/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ImportProfileModel.cs @@ -45,7 +45,7 @@ public partial class ImportProfileModel : EntityModelBase public ScheduleTaskModel TaskModel { get; set; } public bool LogFileExists { get; set; } - public string TempImportFile { get; set; } + public string TempImportFiles { get; set; } public string EntityTypeName { get; set; } } } \ No newline at end of file diff --git a/src/Presentation/SmartStore.Web/Administration/SmartStore.Admin.csproj b/src/Presentation/SmartStore.Web/Administration/SmartStore.Admin.csproj index 1cb806ab59..5b9aafc01f 100644 --- a/src/Presentation/SmartStore.Web/Administration/SmartStore.Admin.csproj +++ b/src/Presentation/SmartStore.Web/Administration/SmartStore.Admin.csproj @@ -539,6 +539,8 @@ + + diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Export/List.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Export/List.cshtml index 9405ee9369..d65ebdf061 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Export/List.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Export/List.cshtml @@ -157,7 +157,6 @@ else url: dialog.attr('data-urldelete'), ask: dialog.find('.modal-ask-delete').text(), callbackSuccess: function (resp) { - refreshGrid(); } }); return false; @@ -233,12 +232,6 @@ else // selected provider changed $(document).on('change', 'select[name="ProviderSystemName"]', toggleProviderDescription); - function refreshGrid() { - setTimeout(function () { - $('#export-profile-list').data('tGrid').ajaxRequest(); - }, 500); - } - function showPrimaryButton(display) { var button = $('#export-profile-dialog').find('.btn-primary').toggle(display); } diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Import/Edit.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Import/Edit.cshtml new file mode 100644 index 0000000000..79250bb6dd --- /dev/null +++ b/src/Presentation/SmartStore.Web/Administration/Views/Import/Edit.cshtml @@ -0,0 +1,37 @@ +@using SmartStore.Admin.Models.DataExchange; +@model ImportProfileModel +@{ + var title = string.Concat(T("Admin.Common.Edit"), " ", T("Common.Profile")); + ViewBag.Title = title; +} + +@using (Html.BeginForm()) +{ +
+
+
+ + @title - @Model.Name @Html.ActionLink("(" + T("Admin.Common.BackToList") + ")", "List") +
+
+ @if (Model.LogFileExists) + { + +  @T("Admin.Configuration.ActivityLog") + + } + + + +
+
+ @Html.Partial("_CreateOrUpdate", Model) +
+} +@Html.DeleteConfirmation("import-profile-delete") \ No newline at end of file diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Import/List.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Import/List.cshtml index 11ae7b52b0..014eac56c2 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Import/List.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Import/List.cshtml @@ -48,7 +48,13 @@ @profile.EntityTypeName
- @(string.Join("
", profile.ExistingFileNames)) + @foreach (var fileName in profile.ExistingFileNames) + { +
+ @Html.IconForFileExtension(Path.GetExtension(fileName), false) + @fileName +
+ }
diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Import/_CreateOrUpdate.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Import/_CreateOrUpdate.cshtml index 15820d8042..fbed22181b 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Import/_CreateOrUpdate.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Import/_CreateOrUpdate.cshtml @@ -7,7 +7,7 @@ @Html.ValidationSummary(false) @Html.HiddenFor(model => model.Id) -@Html.HiddenFor(model => model.TempImportFile) +@Html.HiddenFor(model => model.TempImportFiles) @@ -38,6 +38,28 @@ + + + + + @if (Model.ScheduleTaskId > 0) + { + + + + + } + + +
+   + + @Html.Partial("_ImportFileList", Model) +
+ @Html.SmartLabelFor(x => x.ScheduleTaskId) + + @Html.Action("MinimalTask", "ScheduleTask", new { taskId = Model.ScheduleTaskId, returnUrl = Request.RawUrl, cancellable = true, area = "admin" }) +
 
@Html.SmartLabelFor(x => x.Name) @@ -114,8 +136,25 @@ dataType: 'json', acceptFileTypes: /(\.|\/)(csv|xls|xlsx)$/i, done: function (e, data) { - if (data.result.success && data.result.tempFile.length > 0) { - $('input[name=TempImportFile]').val(data.result.tempFile); + if (data.result.success) { + $('#ImportFileListContainer').show(); + + if (!_.isEmpty(data.result.tempFile)) { + var fileInput = $('input[name=TempImportFiles]'), + files = fileInput.val(); + + if (_.isEmpty(files)) + files = data.result.tempFile; + else + files += '|' + data.result.tempFile; + + fileInput.val(files); + $('#ImportFileList').html(files.replace('|', ', ')); + } + + if (!_.isEmpty(data.result.fileList)) { + $('#ImportFileList').html(data.result.fileList); + } } } }); diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Import/_ImportFileList.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Import/_ImportFileList.cshtml new file mode 100644 index 0000000000..78fc121360 --- /dev/null +++ b/src/Presentation/SmartStore.Web/Administration/Views/Import/_ImportFileList.cshtml @@ -0,0 +1,35 @@ +@using SmartStore.Admin.Models.DataExchange; +@model ImportProfileModel +@foreach (var fileName in Model.ExistingFileNames) +{ +

+ @Html.IconForFileExtension(Path.GetExtension(fileName), false) + @fileName + +   + +

+} + \ No newline at end of file From dc7d4e41d73f3a7833f61bfb741e349dfe466c23 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Fri, 11 Dec 2015 13:14:10 +0100 Subject: [PATCH 076/626] An import file is mandatory for creating an import profile (to specify the file format). Allow to upload further import files while editing a profile (because we allow to export data in multiple files). --- .../Domain/DataExchange/ImportProfile.cs | 10 +- .../Mapping/DataExchange/ImportProfileMap.cs | 1 + .../201512101150534_ImportFramework.resx | 126 ------------------ ...1512111134591_ImportFramework.Designer.cs} | 2 +- ....cs => 201512111134591_ImportFramework.cs} | 14 +- .../201512111134591_ImportFramework.resx | 126 ++++++++++++++++++ .../SmartStore.Data/SmartStore.Data.csproj | 10 +- .../Import/IImportProfileService.cs | 3 +- .../DataExchange/Import/ImportExtensions.cs | 12 +- .../Import/ImportProfileService.cs | 8 +- .../Controllers/ImportController.cs | 45 +++---- .../Models/DataExchange/ImportProfileModel.cs | 22 +-- .../Administration/Views/Export/List.cshtml | 15 +-- .../Administration/Views/Import/List.cshtml | 26 ---- .../Views/Import/_CreateOrUpdate.cshtml | 53 ++++---- .../Views/Import/_ImportFileList.cshtml | 33 +---- .../Content/bootstrap/custom/custom.less | 3 + 17 files changed, 217 insertions(+), 292 deletions(-) delete mode 100644 src/Libraries/SmartStore.Data/Migrations/201512101150534_ImportFramework.resx rename src/Libraries/SmartStore.Data/Migrations/{201512101150534_ImportFramework.Designer.cs => 201512111134591_ImportFramework.Designer.cs} (92%) rename src/Libraries/SmartStore.Data/Migrations/{201512101150534_ImportFramework.cs => 201512111134591_ImportFramework.cs} (86%) create mode 100644 src/Libraries/SmartStore.Data/Migrations/201512111134591_ImportFramework.resx diff --git a/src/Libraries/SmartStore.Core/Domain/DataExchange/ImportProfile.cs b/src/Libraries/SmartStore.Core/Domain/DataExchange/ImportProfile.cs index ccff94629c..2654192757 100644 --- a/src/Libraries/SmartStore.Core/Domain/DataExchange/ImportProfile.cs +++ b/src/Libraries/SmartStore.Core/Domain/DataExchange/ImportProfile.cs @@ -15,6 +15,11 @@ public class ImportProfile : BaseEntity /// public string FolderName { get; set; } + /// + /// The name of the initially uploaded import file + /// + public string FileName { get; set; } + /// /// The identifier of the entity type /// @@ -60,11 +65,6 @@ public ImportEntityType EntityType /// public string ColumnMapping { get; set; } - /// - /// Whether to delete import files after import - /// - public bool Cleanup { get; set; } - /// /// The scheduling task identifier /// diff --git a/src/Libraries/SmartStore.Data/Mapping/DataExchange/ImportProfileMap.cs b/src/Libraries/SmartStore.Data/Mapping/DataExchange/ImportProfileMap.cs index c390eff79d..9b0efcac9d 100644 --- a/src/Libraries/SmartStore.Data/Mapping/DataExchange/ImportProfileMap.cs +++ b/src/Libraries/SmartStore.Data/Mapping/DataExchange/ImportProfileMap.cs @@ -12,6 +12,7 @@ public ImportProfileMap() this.Property(x => x.Name).IsRequired().HasMaxLength(100); this.Property(x => x.FolderName).IsRequired().HasMaxLength(100); + this.Property(x => x.FileName).IsRequired().HasMaxLength(400); this.Property(x => x.FileTypeConfiguration).IsMaxLength(); this.Property(x => x.ColumnMapping).IsMaxLength(); diff --git a/src/Libraries/SmartStore.Data/Migrations/201512101150534_ImportFramework.resx b/src/Libraries/SmartStore.Data/Migrations/201512101150534_ImportFramework.resx deleted file mode 100644 index 641f298bd8..0000000000 --- a/src/Libraries/SmartStore.Data/Migrations/201512101150534_ImportFramework.resx +++ /dev/null @@ -1,126 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 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 - - - dbo - - \ No newline at end of file diff --git a/src/Libraries/SmartStore.Data/Migrations/201512101150534_ImportFramework.Designer.cs b/src/Libraries/SmartStore.Data/Migrations/201512111134591_ImportFramework.Designer.cs similarity index 92% rename from src/Libraries/SmartStore.Data/Migrations/201512101150534_ImportFramework.Designer.cs rename to src/Libraries/SmartStore.Data/Migrations/201512111134591_ImportFramework.Designer.cs index 8f8b2e1554..1d43defd3f 100644 --- a/src/Libraries/SmartStore.Data/Migrations/201512101150534_ImportFramework.Designer.cs +++ b/src/Libraries/SmartStore.Data/Migrations/201512111134591_ImportFramework.Designer.cs @@ -13,7 +13,7 @@ public sealed partial class ImportFramework : IMigrationMetadata string IMigrationMetadata.Id { - get { return "201512101150534_ImportFramework"; } + get { return "201512111134591_ImportFramework"; } } string IMigrationMetadata.Source diff --git a/src/Libraries/SmartStore.Data/Migrations/201512101150534_ImportFramework.cs b/src/Libraries/SmartStore.Data/Migrations/201512111134591_ImportFramework.cs similarity index 86% rename from src/Libraries/SmartStore.Data/Migrations/201512101150534_ImportFramework.cs rename to src/Libraries/SmartStore.Data/Migrations/201512111134591_ImportFramework.cs index dda44fb555..9e3be78b89 100644 --- a/src/Libraries/SmartStore.Data/Migrations/201512101150534_ImportFramework.cs +++ b/src/Libraries/SmartStore.Data/Migrations/201512111134591_ImportFramework.cs @@ -16,13 +16,13 @@ public override void Up() Id = c.Int(nullable: false, identity: true), Name = c.String(nullable: false, maxLength: 100), FolderName = c.String(nullable: false, maxLength: 100), + FileName = c.String(nullable: false, maxLength: 400), EntityTypeId = c.Int(nullable: false), Enabled = c.Boolean(nullable: false), Skip = c.Int(nullable: false), Take = c.Int(nullable: false), FileTypeConfiguration = c.String(), ColumnMapping = c.String(), - Cleanup = c.Boolean(nullable: false), SchedulingTaskId = c.Int(nullable: false), }) .PrimaryKey(t => t.Id) @@ -84,18 +84,6 @@ public void MigrateLocaleResources(LocaleResourcesBuilder builder) "Specifies the name of the import profile.", "Legt den Namen des Importprofils fest."); - builder.AddOrUpdate("Admin.DataExchange.Import.FolderName", - "Folder name", - "Ordnername", - "Specifies the name of the folder where the import files are saved.", - "Legt den Namen des Ordners fest, in den die Importdateien gespeichert werden."); - - builder.AddOrUpdate("Admin.DataExchange.Import.Cleanup", - "Clean up at the end", - "Zum Schluss aufrumen", - "Specifies whether to delete import files after an import.", - "Legt fest, ob die Importdateien nach einem Import gelscht werden sollen."); - builder.AddOrUpdate("Enums.SmartStore.Core.Domain.DataExchange.ImportEntityType.Product", "Product", "Produkt"); builder.AddOrUpdate("Enums.SmartStore.Core.Domain.DataExchange.ImportEntityType.Customer", "Customer", "Kunde"); builder.AddOrUpdate("Enums.SmartStore.Core.Domain.DataExchange.ImportEntityType.NewsLetterSubscription", "Newsletter Subscribers", "Newsletter Abonnenten"); diff --git a/src/Libraries/SmartStore.Data/Migrations/201512111134591_ImportFramework.resx b/src/Libraries/SmartStore.Data/Migrations/201512111134591_ImportFramework.resx new file mode 100644 index 0000000000..1fea63c233 --- /dev/null +++ b/src/Libraries/SmartStore.Data/Migrations/201512111134591_ImportFramework.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 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 + + + dbo + + \ No newline at end of file diff --git a/src/Libraries/SmartStore.Data/SmartStore.Data.csproj b/src/Libraries/SmartStore.Data/SmartStore.Data.csproj index 8272d36d87..f58765ce75 100644 --- a/src/Libraries/SmartStore.Data/SmartStore.Data.csproj +++ b/src/Libraries/SmartStore.Data/SmartStore.Data.csproj @@ -372,9 +372,9 @@ 201511271019577_ExportFramework3.cs - - - 201512101150534_ImportFramework.cs + + + 201512111134591_ImportFramework.cs @@ -699,8 +699,8 @@ 201511271019577_ExportFramework3.cs - - 201512101150534_ImportFramework.cs + + 201512111134591_ImportFramework.cs diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/IImportProfileService.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/IImportProfileService.cs index 366cb9d5bb..ceb9c751c1 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Import/IImportProfileService.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/IImportProfileService.cs @@ -9,10 +9,11 @@ public interface IImportProfileService /// /// Inserts an import profile /// + /// Name of the import file /// Profile name /// /// Inserted import profile - ImportProfile InsertImportProfile(string name, ImportEntityType entityType); + ImportProfile InsertImportProfile(string fileName, string name, ImportEntityType entityType); /// /// Updates an import profile diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportExtensions.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportExtensions.cs index 078a04a460..6e96b65fe1 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportExtensions.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportExtensions.cs @@ -30,16 +30,22 @@ public static string GetImportFolder(this ImportProfile profile, bool content = /// List of file paths public static List GetImportFiles(this ImportProfile profile) { + var result = new List(); var folder = profile.GetImportFolder(true); if (System.IO.Directory.Exists(folder)) { - return System.IO.Directory.EnumerateFiles(folder, "*", SearchOption.TopDirectoryOnly) + var initialImportFile = Path.Combine(folder, profile.FileName); + + result.Add(initialImportFile); + + result.AddRange(System.IO.Directory.EnumerateFiles(folder, "*", SearchOption.TopDirectoryOnly) + .Where(x => !x.IsCaseInsensitiveEqual(initialImportFile)) .OrderBy(x => x) - .ToList(); + .ToList()); } - return new List(); + return result; } /// diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportProfileService.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportProfileService.cs index dce39f68d6..7b4cb63697 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportProfileService.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportProfileService.cs @@ -29,8 +29,9 @@ public ImportProfileService( _dataExchangeSettings = dataExchangeSettings; } - public virtual ImportProfile InsertImportProfile(string name, ImportEntityType entityType) + public virtual ImportProfile InsertImportProfile(string fileName, string name, ImportEntityType entityType) { + Guard.ArgumentNotEmpty(() => fileName); Guard.ArgumentNotEmpty(() => name); var task = new ScheduleTask @@ -49,6 +50,7 @@ public virtual ImportProfile InsertImportProfile(string name, ImportEntityType e var profile = new ImportProfile { Name = name, + FileName = fileName, EntityType = entityType, Enabled = true, SchedulingTaskId = task.Id @@ -73,10 +75,6 @@ public virtual void UpdateImportProfile(ImportProfile profile) if (profile == null) throw new ArgumentNullException("profile"); - profile.FolderName = profile.FolderName - .ToValidPath() - .Truncate(_dataExchangeSettings.MaxFileNameLength); - _importProfileRepository.Update(profile); _eventPublisher.EntityUpdated(profile); diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs index 57997043c6..9727cce98e 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs @@ -50,12 +50,11 @@ private void PrepareProfileModel(ImportProfileModel model, ImportProfile profile { model.Id = profile.Id; model.Name = profile.Name; - model.FolderName = profile.FolderName; + model.FileName = profile.FileName; model.EntityType = profile.EntityType; model.Enabled = profile.Enabled; model.Skip = profile.Skip; model.Take = profile.Take; - model.Cleanup = profile.Cleanup; model.ScheduleTaskId = profile.SchedulingTaskId; model.ScheduleTaskName = profile.ScheduleTask.Name.NaIfEmpty(); model.IsTaskRunning = profile.ScheduleTask.IsRunning; @@ -65,7 +64,6 @@ private void PrepareProfileModel(ImportProfileModel model, ImportProfile profile model.ExistingFileNames = profile.GetImportFiles() .Select(x => Path.GetFileName(x)) - .OrderBy(x => x) .ToList(); } else @@ -116,6 +114,8 @@ public ActionResult Create() var model = new ImportProfileModel(); PrepareProfileModel(model, null, true); + model.Name = T("Common.Import"); + return View(model); } @@ -125,25 +125,21 @@ public ActionResult Create(ImportProfileModel model) if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageImports)) return AccessDeniedView(); - string[] tempFiles = model.TempImportFiles.SplitSafe("|"); + var importFile = Path.Combine(FileSystemHelper.TempDir(), model.FileName); - if (tempFiles.Length == 0) + if (model.FileName.IsEmpty() || !System.IO.File.Exists(importFile)) { - ModelState.AddModelError("ImportFiles", T("Admin.DataExchange.Import.MissingImportFile")); + ModelState.AddModelError("", T("Admin.DataExchange.Import.MissingImportFile")); } else if (ModelState.IsValid) { - var profile = _importService.InsertImportProfile(model.Name, model.EntityType); + var profile = _importService.InsertImportProfile(model.FileName, model.Name, model.EntityType); if (profile != null && profile.Id != 0) { - var folder = profile.GetImportFolder(true, true); - var tempDir = FileSystemHelper.TempDir(); + var importFileDestination = Path.Combine(profile.GetImportFolder(true, true), model.FileName); - foreach (var file in tempFiles) - { - FileSystemHelper.Copy(Path.Combine(tempDir, file), Path.Combine(folder, file), true, true); - } + FileSystemHelper.Copy(importFile, importFileDestination, true, true); return RedirectToAction("Edit", new { id = profile.Id }); } @@ -180,23 +176,18 @@ public ActionResult Edit(ImportProfileModel model, bool continueEditing) if (profile == null) return RedirectToAction("List"); - if (!ModelState.IsValid) + if (ModelState.IsValid) { - PrepareProfileModel(model, profile, true); - return View(model); - } - - profile.Name = model.Name; - profile.FolderName = model.FolderName; - profile.EntityType = model.EntityType; - profile.Enabled = model.Enabled; - profile.Skip = model.Skip; - profile.Take = model.Take; - profile.Cleanup = model.Cleanup; + profile.Name = model.Name; + profile.EntityType = model.EntityType; + profile.Enabled = model.Enabled; + profile.Skip = model.Skip; + profile.Take = model.Take; - _importService.UpdateImportProfile(profile); + _importService.UpdateImportProfile(profile); - NotifySuccess(T("Admin.Common.DataSuccessfullySaved")); + NotifySuccess(T("Admin.Common.DataSuccessfullySaved")); + } return (continueEditing ? RedirectToAction("Edit", new { id = profile.Id }) : RedirectToAction("List")); } diff --git a/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ImportProfileModel.cs b/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ImportProfileModel.cs index 11724f7622..ecf64bc593 100644 --- a/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ImportProfileModel.cs +++ b/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ImportProfileModel.cs @@ -1,4 +1,6 @@ using System.Collections.Generic; +using System.IO; +using System.Linq; using System.Web.Mvc; using FluentValidation.Attributes; using SmartStore.Admin.Models.Tasks; @@ -12,17 +14,22 @@ namespace SmartStore.Admin.Models.DataExchange [Validator(typeof(ImportProfileValidator))] public partial class ImportProfileModel : EntityModelBase { - [SmartResourceDisplayName("Admin.Common.ImportFiles")] - public List ExistingFileNames { get; set; } - [SmartResourceDisplayName("Admin.DataExchange.Import.Name")] public string Name { get; set; } - [SmartResourceDisplayName("Admin.DataExchange.Import.FolderName")] - public string FolderName { get; set; } + public string FileName { get; set; } + + public string FileExtension + { + get { return Path.GetExtension(FileName); } + } + + [SmartResourceDisplayName("Admin.Common.ImportFiles")] + public List ExistingFileNames { get; set; } [SmartResourceDisplayName("Admin.Common.Entity")] public ImportEntityType EntityType { get; set; } + public string EntityTypeName { get; set; } public List AvailableEntityTypes { get; set; } [SmartResourceDisplayName("Common.Enabled")] @@ -34,9 +41,6 @@ public partial class ImportProfileModel : EntityModelBase [SmartResourceDisplayName("Admin.Common.RecordsTake")] public int Take { get; set; } - [SmartResourceDisplayName("Admin.DataExchange.Import.Cleanup")] - public bool Cleanup { get; set; } - [SmartResourceDisplayName("Common.Execution")] public int ScheduleTaskId { get; set; } public string ScheduleTaskName { get; set; } @@ -45,7 +49,5 @@ public partial class ImportProfileModel : EntityModelBase public ScheduleTaskModel TaskModel { get; set; } public bool LogFileExists { get; set; } - public string TempImportFiles { get; set; } - public string EntityTypeName { get; set; } } } \ No newline at end of file diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Export/List.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Export/List.cshtml index d65ebdf061..520d95b0a1 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Export/List.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Export/List.cshtml @@ -118,13 +118,12 @@ else } -
+@if (Model.CsvConfiguration != null) +{ + var viewData = new ViewDataDictionary(); + viewData.Add("ShowGroupCaption", true); + viewData.TemplateInfo.HtmlFieldPrefix = "CsvConfiguration"; + viewData.ModelState.Merge(ViewData.ModelState); + @Html.Partial("CsvConfiguration", Model.CsvConfiguration, viewData) +} + - -@*import emails form*@ -@{Html.SmartStore().Window() - .Name("importcsv-window") - .Title(T("Admin.Common.ImportFromCsv").Text) - .Content(@ - @using (Html.BeginForm("ImportCsv", "NewsLetterSubscription", FormMethod.Post, new { enctype = "multipart/form-data" })) - { -
- @T("Admin.Common.CsvFile"): -
- } -
) - .FooterContent(@ - - ) - .Width(400) - .Modal(true) - .Visible(false) - .Render(); -} - - + \ No newline at end of file diff --git a/src/Tests/SmartStore.Services.Tests/Messages/NewsLetterSubscriptionServiceTests.cs b/src/Tests/SmartStore.Services.Tests/Messages/NewsLetterSubscriptionServiceTests.cs index 843e2c60ca..bce6703f67 100644 --- a/src/Tests/SmartStore.Services.Tests/Messages/NewsLetterSubscriptionServiceTests.cs +++ b/src/Tests/SmartStore.Services.Tests/Messages/NewsLetterSubscriptionServiceTests.cs @@ -1,20 +1,18 @@ -using SmartStore.Core.Data; +using NUnit.Framework; +using Rhino.Mocks; +using SmartStore.Core.Data; using SmartStore.Core.Domain.Messages; using SmartStore.Core.Events; using SmartStore.Services.Messages; -using NUnit.Framework; -using Rhino.Mocks; -using SmartStore.Services.Stores; namespace SmartStore.Services.Tests.Messages { - [TestFixture] + [TestFixture] public class NewsLetterSubscriptionServiceTests : ServiceTest { IEventPublisher _eventPublisher; IRepository _subscriptionRepository; IDbContext _dbContext; - IStoreService _storeService; NewsLetterSubscriptionService _newsLetterSubscriptionService; [SetUp] @@ -23,9 +21,8 @@ public class NewsLetterSubscriptionServiceTests : ServiceTest _eventPublisher = MockRepository.GenerateStub(); _subscriptionRepository = MockRepository.GenerateStub>(); _dbContext = MockRepository.GenerateStub(); - _storeService = MockRepository.GenerateStub(); - _newsLetterSubscriptionService = new NewsLetterSubscriptionService(_dbContext, _subscriptionRepository, _eventPublisher, _storeService); + _newsLetterSubscriptionService = new NewsLetterSubscriptionService(_dbContext, _subscriptionRepository, _eventPublisher); } /// From 2276ea63b9e650f11229c87caeaaea10017d8300 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Mon, 14 Dec 2015 12:18:01 +0100 Subject: [PATCH 085/626] Export framework should check permission for export entity --- .../DataExchange/DataExportTask.cs | 1 + .../DataExchange/DataExporter.cs | 46 ++++++++++++++++--- .../DataExchange/IDataExporter.cs | 2 + .../DataExchange/Import/DataImporter.cs | 3 ++ .../Controllers/ExportController.cs | 10 ++-- 5 files changed, 50 insertions(+), 12 deletions(-) diff --git a/src/Libraries/SmartStore.Services/DataExchange/DataExportTask.cs b/src/Libraries/SmartStore.Services/DataExchange/DataExportTask.cs index 8d8aa30923..ba4356de43 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/DataExportTask.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/DataExportTask.cs @@ -32,6 +32,7 @@ public void Execute(TaskExecutionContext ctx) // build export request var request = new DataExportRequest(profile, provider); + request.CustomerId = ctx.Parameters["CurrentCustomerId"].ToInt(); // do not use built-in background tasks customer request.ProgressValueSetter = delegate(int val, int max, string msg) { diff --git a/src/Libraries/SmartStore.Services/DataExchange/DataExporter.cs b/src/Libraries/SmartStore.Services/DataExchange/DataExporter.cs index f9bc604ab3..1b56c39d1c 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/DataExporter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/DataExporter.cs @@ -30,6 +30,7 @@ using SmartStore.Services.Media; using SmartStore.Services.Messages; using SmartStore.Services.Orders; +using SmartStore.Services.Security; using SmartStore.Services.Seo; using SmartStore.Services.Shipping; using SmartStore.Services.Tax; @@ -63,7 +64,7 @@ public partial class DataExporter : IDataExporter private readonly Lazy _productService; private readonly Lazy _orderService; private readonly Lazy _manufacturerService; - private readonly Lazy _customerService; + private readonly ICustomerService _customerService; private readonly Lazy _addressService; private readonly Lazy _countryService; private readonly Lazy _shipmentService; @@ -102,7 +103,7 @@ public DataExporter( Lazy productService, Lazy orderService, Lazy manufacturerService, - Lazy customerService, + ICustomerService customerService, Lazy addressService, Lazy countryService, Lazy shipmentService, @@ -199,6 +200,30 @@ private void SetProgress(DataExporterContext ctx, string message) catch { } } + private bool HasPermission(DataExporterContext ctx) + { + if (ctx.Request.CustomerId == 0) + ctx.Request.CustomerId = _services.WorkContext.CurrentCustomer.Id; + + var customer = _customerService.GetCustomerById(ctx.Request.CustomerId); + + if (ctx.Request.Provider.Value.EntityType == ExportEntityType.Product || + ctx.Request.Provider.Value.EntityType == ExportEntityType.Category || + ctx.Request.Provider.Value.EntityType == ExportEntityType.Manufacturer) + return _services.Permissions.Authorize(StandardPermissionProvider.ManageCatalog, customer); + + if (ctx.Request.Provider.Value.EntityType == ExportEntityType.Customer) + return _services.Permissions.Authorize(StandardPermissionProvider.ManageCustomers, customer); + + if (ctx.Request.Provider.Value.EntityType == ExportEntityType.Order) + return _services.Permissions.Authorize(StandardPermissionProvider.ManageOrders, customer); + + if (ctx.Request.Provider.Value.EntityType == ExportEntityType.NewsLetterSubscription) + return _services.Permissions.Authorize(StandardPermissionProvider.ManageNewsletterSubscribers, customer); + + return true; + } + private void DetachAllEntitiesAndClear(DataExporterContext ctx) { try @@ -285,8 +310,8 @@ private IExportDataSegmenterProvider CreateSegmenter(DataExporterContext ctx, in entities => { ctx.OrderExportContext = new OrderExportContext(entities, - x => _customerService.Value.GetCustomersByIds(x), - x => _customerService.Value.GetRewardPointsHistoriesByCustomerIds(x), + x => _customerService.GetCustomersByIds(x), + x => _customerService.GetRewardPointsHistoriesByCustomerIds(x), x => _addressService.Value.GetAddressByIds(x), x => _orderService.Value.GetOrderItemsByOrderIds(x), x => _shipmentService.Value.GetShipmentsByOrderIds(x) @@ -839,13 +864,16 @@ private List Init(DataExporterContext ctx, int? totalRecords = null) // Init base things that are even required for preview. Init all other things (regular export) in ExportCoreOuter. List result = null; + if (ctx.Request.CustomerId == 0) + ctx.Request.CustomerId = _services.WorkContext.CurrentCustomer.Id; + if (ctx.Projection.CurrencyId.HasValue) ctx.ContextCurrency = _currencyService.Value.GetCurrencyById(ctx.Projection.CurrencyId.Value); else ctx.ContextCurrency = _services.WorkContext.WorkingCurrency; if (ctx.Projection.CustomerId.HasValue) - ctx.ContextCustomer = _customerService.Value.GetCustomerById(ctx.Projection.CustomerId.Value); + ctx.ContextCustomer = _customerService.GetCustomerById(ctx.Projection.CustomerId.Value); else ctx.ContextCustomer = _services.WorkContext.CurrentCustomer; @@ -1045,9 +1073,10 @@ private void ExportCoreOuter(DataExporterContext ctx) try { if (!ctx.Request.Provider.IsValid()) - { throw new SmartException("Export aborted because the export provider is not valid"); - } + + if (!HasPermission(ctx)) + throw new SmartException("You do not have permission to perform the selected export"); foreach (var item in ctx.Request.CustomData) { @@ -1298,6 +1327,9 @@ public IList Preview(DataExportRequest request, int pageIndex, int? tot var unused = Init(ctx, totalRecords); + if (!HasPermission(ctx)) + throw new SmartException("You do not have permission to perform the selected export"); + using (var segmenter = CreateSegmenter(ctx, pageIndex)) { if (segmenter == null) diff --git a/src/Libraries/SmartStore.Services/DataExchange/IDataExporter.cs b/src/Libraries/SmartStore.Services/DataExchange/IDataExporter.cs index b1c2dacf7d..8e30fa9974 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/IDataExporter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/IDataExporter.cs @@ -42,6 +42,8 @@ public DataExportRequest(ExportProfile profile, Provider provid public ProgressValueSetter ProgressValueSetter { get; set; } + public int CustomerId { get; set; } + public IList EntitiesToExport { get; set; } public IDictionary CustomData { get; private set; } diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/DataImporter.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/DataImporter.cs index 1e0153c2b1..b2ff901499 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Import/DataImporter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/DataImporter.cs @@ -110,6 +110,9 @@ private void ImportCoreOuter(DataImporterContext ctx) if (ctx.Request.Profile == null || !ctx.Request.Profile.Enabled) return; + if (ctx.Request.CustomerId == 0) + ctx.Request.CustomerId = _services.WorkContext.CurrentCustomer.Id; + var logPath = ctx.Request.Profile.GetImportLogPath(); FileSystemHelper.Delete(logPath); diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs index 904d8a4089..1a7a72e057 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs @@ -975,20 +975,20 @@ public ActionResult PreviewList(GridCommand command, int id, int totalRecords) [HttpPost] public ActionResult Execute(int id, string selectedIds) { - if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageExports)) + var customer = _services.WorkContext.CurrentCustomer; + + if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageExports, customer)) return AccessDeniedView(); var profile = _exportService.GetExportProfileById(id); if (profile == null) return RedirectToAction("List"); - Dictionary taskParams = null; + var taskParams = new Dictionary(); + taskParams.Add("CurrentCustomerId", customer.Id.ToString()); if (selectedIds.HasValue()) - { - taskParams = new Dictionary(); taskParams.Add("SelectedIds", selectedIds); - } _taskScheduler.RunSingleTask(profile.SchedulingTaskId, taskParams); From f6d434a30ca03072345ddf5e07d3cf48582ae98e Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Tue, 15 Dec 2015 14:00:32 +0100 Subject: [PATCH 086/626] Getting started to support import framework for product import --- .../Catalog/Importer/ProductImporter.cs | 658 ++++++++++++++++++ .../DataExchange/DataExportTask.cs | 8 +- .../DataExchange/DataExporter.cs | 32 +- .../DataExchange/Import/DataImportTask.cs | 6 +- .../DataExchange/Import/DataImporter.cs | 159 ++++- .../DataExchange/Import/IEntityImporter.cs | 26 +- .../DataExchange/Import/ImportResult.cs | 22 +- .../Internal/DataExporterContext.cs | 4 + .../NewsLetterSubscriptionImporter.cs | 19 +- .../SmartStore.Services.csproj | 1 + .../Controllers/ExportController.cs | 7 +- .../Controllers/ImportController.cs | 7 +- 12 files changed, 867 insertions(+), 82 deletions(-) create mode 100644 src/Libraries/SmartStore.Services/Catalog/Importer/ProductImporter.cs diff --git a/src/Libraries/SmartStore.Services/Catalog/Importer/ProductImporter.cs b/src/Libraries/SmartStore.Services/Catalog/Importer/ProductImporter.cs new file mode 100644 index 0000000000..bfd2d5d27d --- /dev/null +++ b/src/Libraries/SmartStore.Services/Catalog/Importer/ProductImporter.cs @@ -0,0 +1,658 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using SmartStore.Core.Data; +using SmartStore.Core.Domain.Catalog; +using SmartStore.Core.Domain.DataExchange; +using SmartStore.Core.Domain.Seo; +using SmartStore.Core.Events; +using SmartStore.Services.DataExchange.Import; +using SmartStore.Services.Localization; +using SmartStore.Services.Media; +using SmartStore.Services.Seo; +using SmartStore.Services.Stores; +using SmartStore.Utilities; + +namespace SmartStore.Services.Catalog.Importer +{ + public class ProductImporter : IEntityImporter + { + private readonly IRepository _rsProductPicture; + private readonly IRepository _rsProductManufacturer; + private readonly IRepository _rsProductCategory; + private readonly IRepository _rsUrlRecord; + private readonly IRepository _rsProduct; + private readonly ICommonServices _services; + private readonly ILanguageService _languageService; + private readonly ILocalizedEntityService _localizedEntityService; + private readonly IPictureService _pictureService; + private readonly IManufacturerService _manufacturerService; + private readonly ICategoryService _categoryService; + private readonly IProductService _productService; + private readonly IUrlRecordService _urlRecordService; + private readonly IStoreMappingService _storeMappingService; + private readonly SeoSettings _seoSettings; + + public ProductImporter( + IRepository rsProductPicture, + IRepository rsProductManufacturer, + IRepository rsProductCategory, + IRepository rsUrlRecord, + IRepository rsProduct, + ICommonServices services, + ILanguageService languageService, + ILocalizedEntityService localizedEntityService, + IPictureService pictureService, + IManufacturerService manufacturerService, + ICategoryService categoryService, + IProductService productService, + IUrlRecordService urlRecordService, + IStoreMappingService storeMappingService, + SeoSettings seoSettings) + { + _rsProductPicture = rsProductPicture; + _rsProductManufacturer = rsProductManufacturer; + _rsProductCategory = rsProductCategory; + _rsUrlRecord = rsUrlRecord; + _rsProduct = rsProduct; + _services = services; + _languageService = languageService; + _localizedEntityService = localizedEntityService; + _pictureService = pictureService; + _manufacturerService = manufacturerService; + _categoryService = categoryService; + _productService = productService; + _urlRecordService = urlRecordService; + _storeMappingService = storeMappingService; + _seoSettings = seoSettings; + } + + private int? ZeroToNull(object value, CultureInfo culture) + { + int result; + if (CommonHelper.TryConvert(value, culture, out result) && result > 0) + { + return result; + } + + return (int?)null; + } + + private void ProcessProductPictures(ImportExecuteContext context, ImportRow[] batch) + { + // true, cause pictures must be saved and assigned an id + // prior adding a mapping. + _rsProductPicture.AutoCommitEnabled = true; + + ProductPicture lastInserted = null; + int equalPictureId = 0; + + foreach (var row in batch) + { + var pictures = new string[] + { + row.GetDataValue("Picture1"), + row.GetDataValue("Picture2"), + row.GetDataValue("Picture3") + }; + + int i = 0; + try + { + for (i = 0; i < pictures.Length; i++) + { + var picture = pictures[i]; + + if (picture.IsEmpty() || !File.Exists(picture)) + continue; + + var currentPictures = _rsProductPicture.TableUntracked.Expand(x => x.Picture).Where(x => x.ProductId == row.Entity.Id).Select(x => x.Picture).ToList(); + var pictureBinary = _pictureService.FindEqualPicture(picture, currentPictures, out equalPictureId); + + if (pictureBinary != null && pictureBinary.Length > 0) + { + // no equal picture found in sequence + var newPicture = _pictureService.InsertPicture(pictureBinary, "image/jpeg", _pictureService.GetPictureSeName(row.EntityDisplayName), true, false, false); + if (newPicture != null) + { + var mapping = new ProductPicture + { + ProductId = row.Entity.Id, + PictureId = newPicture.Id, + DisplayOrder = 1, + }; + _rsProductPicture.Insert(mapping); + lastInserted = mapping; + } + } + else + { + context.Result.AddInfo("Found equal picture in data store. Skipping field.", row.GetRowInfo(), "Picture" + (i + 1).ToString()); + } + } + } + catch (Exception exception) + { + context.Result.AddWarning(exception.Message, row.GetRowInfo(), "Picture" + (i + 1).ToString()); + } + + } + + // Perf: notify only about LAST insertion and update + if (lastInserted != null) + _services.EventPublisher.EntityInserted(lastInserted); + } + + private int ProcessProductManufacturers(ImportExecuteContext context, ImportRow[] batch) + { + _rsProductManufacturer.AutoCommitEnabled = false; + + ProductManufacturer lastInserted = null; + + foreach (var row in batch) + { + var manufacturerIds = row.GetDataValue>("ManufacturerIds"); + if (manufacturerIds != null && manufacturerIds.Any()) + { + try + { + foreach (var id in manufacturerIds) + { + if (_rsProductManufacturer.TableUntracked.Where(x => x.ProductId == row.Entity.Id && x.ManufacturerId == id).FirstOrDefault() == null) + { + // ensure that manufacturer exists + var manufacturer = _manufacturerService.GetManufacturerById(id); + if (manufacturer != null) + { + var productManufacturer = new ProductManufacturer + { + ProductId = row.Entity.Id, + ManufacturerId = manufacturer.Id, + IsFeaturedProduct = false, + DisplayOrder = 1 + }; + _rsProductManufacturer.Insert(productManufacturer); + lastInserted = productManufacturer; + } + } + } + } + catch (Exception exception) + { + context.Result.AddWarning(exception.Message, row.GetRowInfo(), "ManufacturerIds"); + } + } + } + + // commit whole batch at once + var num = _rsProductManufacturer.Context.SaveChanges(); + + // Perf: notify only about LAST insertion and update + if (lastInserted != null) + _services.EventPublisher.EntityInserted(lastInserted); + + return num; + } + + private int ProcessProductCategories(ImportExecuteContext context, ImportRow[] batch) + { + _rsProductCategory.AutoCommitEnabled = false; + + ProductCategory lastInserted = null; + + foreach (var row in batch) + { + var categoryIds = row.GetDataValue>("CategoryIds"); + if (categoryIds != null && categoryIds.Any()) + { + try + { + foreach (var id in categoryIds) + { + if (_rsProductCategory.TableUntracked.Where(x => x.ProductId == row.Entity.Id && x.CategoryId == id).FirstOrDefault() == null) + { + // ensure that category exists + var category = _categoryService.GetCategoryById(id); + if (category != null) + { + var productCategory = new ProductCategory + { + ProductId = row.Entity.Id, + CategoryId = category.Id, + IsFeaturedProduct = false, + DisplayOrder = 1 + }; + _rsProductCategory.Insert(productCategory); + lastInserted = productCategory; + } + } + } + } + catch (Exception exception) + { + context.Result.AddWarning(exception.Message, row.GetRowInfo(), "CategoryIds"); + } + } + } + + // commit whole batch at once + var num = _rsProductCategory.Context.SaveChanges(); + + // Perf: notify only about LAST insertion and update + if (lastInserted != null) + _services.EventPublisher.EntityInserted(lastInserted); + + return num; + } + + private int ProcessLocalizations(ImportExecuteContext context, ImportRow[] batch) + { + //_rsProductManufacturer.AutoCommitEnabled = false; + + //string lastInserted = null; + + var languages = _languageService.GetAllLanguages(true); + + foreach (var row in batch) + { + + Product product = null; + + //get product + try + { + product = _productService.GetProductById(row.Entity.Id); + } + catch (Exception exception) + { + context.Result.AddWarning(exception.Message, row.GetRowInfo(), "ProcessLocalizations Product"); + } + + foreach (var lang in languages) + { + string localizedName = row.GetDataValue("Name", lang.UniqueSeoCode); + string localizedShortDescription = row.GetDataValue("ShortDescription", lang.UniqueSeoCode); + string localizedFullDescription = row.GetDataValue("FullDescription", lang.UniqueSeoCode); + + if (localizedName.HasValue()) + { + _localizedEntityService.SaveLocalizedValue(product, x => x.Name, localizedName, lang.Id); + } + if (localizedShortDescription.HasValue()) + { + _localizedEntityService.SaveLocalizedValue(product, x => x.ShortDescription, localizedShortDescription, lang.Id); + } + if (localizedFullDescription.HasValue()) + { + _localizedEntityService.SaveLocalizedValue(product, x => x.FullDescription, localizedFullDescription, lang.Id); + } + } + } + + // commit whole batch at once + var num = _rsProductManufacturer.Context.SaveChanges(); + + // Perf: notify only about LAST insertion and update + //if (lastInserted != null) + // _eventPublisher.EntityInserted(lastInserted); + + return num; + } + + private int ProcessSlugs(ImportExecuteContext context, ImportRow[] batch) + { + var slugMap = new Dictionary(100); + Func slugLookup = ((s) => + { + if (slugMap.ContainsKey(s)) + { + return slugMap[s]; + } + return (UrlRecord)null; + }); + + var entityName = typeof(Product).Name; + + foreach (var row in batch) + { + if (row.IsNew || row.NameChanged || row.Segmenter.HasDataColumn("SeName")) + { + try + { + string seName = row.GetDataValue("SeName"); + seName = row.Entity.ValidateSeName(seName, row.Entity.Name, true, _urlRecordService, _seoSettings, extraSlugLookup: slugLookup); + + UrlRecord urlRecord = null; + + if (row.IsNew) + { + // dont't bother validating SeName for new entities. + urlRecord = new UrlRecord + { + EntityId = row.Entity.Id, + EntityName = entityName, + Slug = seName, + LanguageId = 0, + IsActive = true, + }; + _rsUrlRecord.Insert(urlRecord); + } + else + { + urlRecord = _urlRecordService.SaveSlug(row.Entity, seName, 0); + } + + if (urlRecord != null) + { + // a new record was inserted to the store: keep track of it for this batch. + slugMap[seName] = urlRecord; + } + } + catch (Exception exception) + { + context.Result.AddWarning(exception.Message, row.GetRowInfo(), "SeName"); + } + } + } + + // commit whole batch at once + return _rsUrlRecord.Context.SaveChanges(); + } + + private int ProcessProducts(ImportExecuteContext context, ImportRow[] batch) + { + _rsProduct.AutoCommitEnabled = true; + + Product lastInserted = null; + Product lastUpdated = null; + + foreach (var row in batch) + { + Product product = null; + + object key; + var dataRow = row.DataRow; + + // try get by int ID + if (dataRow.TryGetValue("Id", out key) && key.ToString().ToInt() > 0) + { + product = _productService.GetProductById(key.ToString().ToInt()); + } + + // try get by SKU + if (product == null && dataRow.TryGetValue("SKU", out key)) + { + product = _productService.GetProductBySku(key.ToString()); + } + + // try get by GTIN + if (product == null && dataRow.TryGetValue("Gtin", out key)) + { + product = _productService.GetProductByGtin(key.ToString()); + } + + if (product == null) + { + // a Name is required with new products. + if (!row.Segmenter.HasDataColumn("Name")) + { + context.Result.AddError("The 'Name' field is required for new products. Skipping row.", row.GetRowInfo(), "Name"); + continue; + } + product = new Product(); + } + + string name = row.GetDataValue("Name"); + + row.Initialize(product, name); + + if (!row.IsNew) + { + if (!product.Name.Equals(name, StringComparison.OrdinalIgnoreCase)) + { + // Perf: use this later for SeName updates. + row.NameChanged = true; + } + } + + row.SetProperty(context.Result, product, (x) => x.Sku); + row.SetProperty(context.Result, product, (x) => x.Gtin); + row.SetProperty(context.Result, product, (x) => x.ManufacturerPartNumber); + row.SetProperty(context.Result, product, (x) => x.ProductTypeId, (int)ProductType.SimpleProduct); + row.SetProperty(context.Result, product, (x) => x.ParentGroupedProductId); + row.SetProperty(context.Result, product, (x) => x.VisibleIndividually, true); + row.SetProperty(context.Result, product, (x) => x.Name); + row.SetProperty(context.Result, product, (x) => x.ShortDescription); + row.SetProperty(context.Result, product, (x) => x.FullDescription); + row.SetProperty(context.Result, product, (x) => x.ProductTemplateId); + row.SetProperty(context.Result, product, (x) => x.ShowOnHomePage); + row.SetProperty(context.Result, product, (x) => x.HomePageDisplayOrder); + row.SetProperty(context.Result, product, (x) => x.MetaKeywords); + row.SetProperty(context.Result, product, (x) => x.MetaDescription); + row.SetProperty(context.Result, product, (x) => x.MetaTitle); + row.SetProperty(context.Result, product, (x) => x.AllowCustomerReviews, true); + row.SetProperty(context.Result, product, (x) => x.Published, true); + row.SetProperty(context.Result, product, (x) => x.IsGiftCard); + row.SetProperty(context.Result, product, (x) => x.GiftCardTypeId); + row.SetProperty(context.Result, product, (x) => x.RequireOtherProducts); + row.SetProperty(context.Result, product, (x) => x.RequiredProductIds); + row.SetProperty(context.Result, product, (x) => x.AutomaticallyAddRequiredProducts); + row.SetProperty(context.Result, product, (x) => x.IsDownload); + row.SetProperty(context.Result, product, (x) => x.DownloadId); + row.SetProperty(context.Result, product, (x) => x.UnlimitedDownloads, true); + row.SetProperty(context.Result, product, (x) => x.MaxNumberOfDownloads, 10); + row.SetProperty(context.Result, product, (x) => x.DownloadActivationTypeId, 1); + row.SetProperty(context.Result, product, (x) => x.HasSampleDownload); + row.SetProperty(context.Result, product, (x) => x.SampleDownloadId, (int?)null, ZeroToNull); + row.SetProperty(context.Result, product, (x) => x.HasUserAgreement); + row.SetProperty(context.Result, product, (x) => x.UserAgreementText); + row.SetProperty(context.Result, product, (x) => x.IsRecurring); + row.SetProperty(context.Result, product, (x) => x.RecurringCycleLength, 100); + row.SetProperty(context.Result, product, (x) => x.RecurringCyclePeriodId); + row.SetProperty(context.Result, product, (x) => x.RecurringTotalCycles, 10); + row.SetProperty(context.Result, product, (x) => x.IsShipEnabled, true); + row.SetProperty(context.Result, product, (x) => x.IsFreeShipping); + row.SetProperty(context.Result, product, (x) => x.AdditionalShippingCharge); + row.SetProperty(context.Result, product, (x) => x.IsEsd); + row.SetProperty(context.Result, product, (x) => x.IsTaxExempt); + row.SetProperty(context.Result, product, (x) => x.TaxCategoryId, 1); + row.SetProperty(context.Result, product, (x) => x.ManageInventoryMethodId); + row.SetProperty(context.Result, product, (x) => x.StockQuantity, 10000); + row.SetProperty(context.Result, product, (x) => x.DisplayStockAvailability); + row.SetProperty(context.Result, product, (x) => x.DisplayStockQuantity); + row.SetProperty(context.Result, product, (x) => x.MinStockQuantity); + row.SetProperty(context.Result, product, (x) => x.LowStockActivityId); + row.SetProperty(context.Result, product, (x) => x.NotifyAdminForQuantityBelow, 1); + row.SetProperty(context.Result, product, (x) => x.BackorderModeId); + row.SetProperty(context.Result, product, (x) => x.AllowBackInStockSubscriptions); + row.SetProperty(context.Result, product, (x) => x.OrderMinimumQuantity, 1); + row.SetProperty(context.Result, product, (x) => x.OrderMaximumQuantity, 10000); + row.SetProperty(context.Result, product, (x) => x.AllowedQuantities); + row.SetProperty(context.Result, product, (x) => x.DisableBuyButton); + row.SetProperty(context.Result, product, (x) => x.DisableWishlistButton); + row.SetProperty(context.Result, product, (x) => x.AvailableForPreOrder); + row.SetProperty(context.Result, product, (x) => x.CallForPrice); + row.SetProperty(context.Result, product, (x) => x.Price); + row.SetProperty(context.Result, product, (x) => x.OldPrice); + row.SetProperty(context.Result, product, (x) => x.ProductCost); + row.SetProperty(context.Result, product, (x) => x.SpecialPrice); + row.SetProperty(context.Result, product, (x) => x.SpecialPriceStartDateTimeUtc); + row.SetProperty(context.Result, product, (x) => x.SpecialPriceEndDateTimeUtc); + row.SetProperty(context.Result, product, (x) => x.CustomerEntersPrice); + row.SetProperty(context.Result, product, (x) => x.MinimumCustomerEnteredPrice); + row.SetProperty(context.Result, product, (x) => x.MaximumCustomerEnteredPrice, 1000); + row.SetProperty(context.Result, product, (x) => x.Weight); + row.SetProperty(context.Result, product, (x) => x.Length); + row.SetProperty(context.Result, product, (x) => x.Width); + row.SetProperty(context.Result, product, (x) => x.Height); + row.SetProperty(context.Result, product, (x) => x.DeliveryTimeId); + row.SetProperty(context.Result, product, (x) => x.QuantityUnitId); + row.SetProperty(context.Result, product, (x) => x.BasePriceEnabled); + row.SetProperty(context.Result, product, (x) => x.BasePriceMeasureUnit); + row.SetProperty(context.Result, product, (x) => x.BasePriceAmount); + row.SetProperty(context.Result, product, (x) => x.BasePriceBaseAmount); + row.SetProperty(context.Result, product, (x) => x.BundlePerItemPricing); + row.SetProperty(context.Result, product, (x) => x.BundlePerItemShipping); + row.SetProperty(context.Result, product, (x) => x.BundlePerItemShoppingCart); + row.SetProperty(context.Result, product, (x) => x.BundleTitleText); + row.SetProperty(context.Result, product, (x) => x.AvailableStartDateTimeUtc); + row.SetProperty(context.Result, product, (x) => x.AvailableEndDateTimeUtc); + row.SetProperty(context.Result, product, (x) => x.LimitedToStores); + + var storeIds = row.GetDataValue>("StoreIds"); + if (storeIds != null && storeIds.Any()) + { + _storeMappingService.SaveStoreMappings(product, storeIds.ToArray()); + } + + row.SetProperty(context.Result, product, (x) => x.CreatedOnUtc, DateTime.UtcNow); + + product.UpdatedOnUtc = DateTime.UtcNow; + + if (row.IsTransient) + { + _rsProduct.Insert(product); + lastInserted = product; + } + else + { + _rsProduct.Update(product); + lastUpdated = product; + } + } + + // commit whole batch at once + var num = _rsProduct.Context.SaveChanges(); + + // Perf: notify only about LAST insertion and update + if (lastInserted != null) + _services.EventPublisher.EntityInserted(lastInserted); + if (lastUpdated != null) + _services.EventPublisher.EntityUpdated(lastUpdated); + + return num; + } + + public void Execute(ImportExecuteContext context) + { + using (var scope = new DbContextScope(ctx: _rsProduct.Context, autoDetectChanges: false, proxyCreation: false, validateOnSave: false)) + { + var segmenter = new ImportDataSegmenter(context.DataTable); + segmenter.Culture = CultureInfo.CurrentUICulture; + + context.Result.TotalRecords = segmenter.TotalRows; + + while (context.Abort == DataExchangeAbortion.None && segmenter.ReadNextBatch()) + { + var batch = segmenter.CurrentBatch; + + // Perf: detach all entities + _rsProduct.Context.DetachAll(false); + + context.SetProgress(segmenter.CurrentSegmentFirstRowIndex - 1, segmenter.TotalRows); + + // =========================================================================== + // 1.) Import products + // =========================================================================== + try + { + ProcessProducts(context, batch); + } + catch (Exception exception) + { + context.Result.AddError(exception, segmenter.CurrentSegment, "ProcessProducts"); + } + + // reduce batch to saved (valid) products. + // No need to perform import operations on errored products. + batch = batch.Where(x => x.Entity != null && !x.IsTransient).ToArray(); + + // update result object + context.Result.NewRecords += batch.Count(x => x.IsNew && !x.IsTransient); + context.Result.ModifiedRecords += batch.Count(x => !x.IsNew && !x.IsTransient); + + // =========================================================================== + // 2.) Import SEO Slugs + // IMPORTANT: Unlike with Products AutoCommitEnabled must be TRUE, + // as Slugs are going to be validated against existing ones in DB. + // =========================================================================== + if (context.DataTable.HasColumn("SeName") || batch.Any(x => x.IsNew || x.NameChanged)) + { + try + { + _rsProduct.Context.AutoDetectChangesEnabled = true; + ProcessSlugs(context, batch); + } + catch (Exception exception) + { + context.Result.AddError(exception, segmenter.CurrentSegment, "ProcessSeoSlugs"); + } + finally + { + _rsProduct.Context.AutoDetectChangesEnabled = false; + } + } + + // =========================================================================== + // 3.) Import Localizations + // =========================================================================== + try + { + ProcessLocalizations(context, batch); + } + catch (Exception exception) + { + context.Result.AddError(exception, segmenter.CurrentSegment, "ProcessLocalizations"); + } + + // =========================================================================== + // 4.) Import product category mappings + // =========================================================================== + if (context.DataTable.HasColumn("CategoryIds")) + { + try + { + ProcessProductCategories(context, batch); + } + catch (Exception exception) + { + context.Result.AddError(exception, segmenter.CurrentSegment, "ProcessProductCategories"); + } + } + + // =========================================================================== + // 5.) Import product manufacturer mappings + // =========================================================================== + if (context.DataTable.HasColumn("ManufacturerIds")) + { + try + { + ProcessProductManufacturers(context, batch); + } + catch (Exception exception) + { + context.Result.AddError(exception, segmenter.CurrentSegment, "ProcessProductManufacturers"); + } + } + + // =========================================================================== + // 6.) Import product picture mappings + // =========================================================================== + if (context.DataTable.HasColumn("Picture1") || context.DataTable.HasColumn("Picture2") || context.DataTable.HasColumn("Picture3")) + { + try + { + ProcessProductPictures(context, batch); + } + catch (Exception exception) + { + context.Result.AddError(exception, segmenter.CurrentSegment, "ProcessProductPictures"); + } + } + } + } + } + } +} diff --git a/src/Libraries/SmartStore.Services/DataExchange/DataExportTask.cs b/src/Libraries/SmartStore.Services/DataExchange/DataExportTask.cs index ba4356de43..213d23f387 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/DataExportTask.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/DataExportTask.cs @@ -32,13 +32,17 @@ public void Execute(TaskExecutionContext ctx) // build export request var request = new DataExportRequest(profile, provider); - request.CustomerId = ctx.Parameters["CurrentCustomerId"].ToInt(); // do not use built-in background tasks customer - request.ProgressValueSetter = delegate(int val, int max, string msg) + request.ProgressValueSetter = delegate (int val, int max, string msg) { ctx.SetProgress(val, max, msg, true); }; + if (ctx.Parameters.ContainsKey("CurrentCustomerId")) + { + request.CustomerId = ctx.Parameters["CurrentCustomerId"].ToInt(); // do not use built-in background tasks customer + } + if (ctx.Parameters.ContainsKey("SelectedIds")) { request.EntitiesToExport = ctx.Parameters["SelectedIds"] diff --git a/src/Libraries/SmartStore.Services/DataExchange/DataExporter.cs b/src/Libraries/SmartStore.Services/DataExchange/DataExporter.cs index 1b56c39d1c..d8d3006017 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/DataExporter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/DataExporter.cs @@ -203,7 +203,7 @@ private void SetProgress(DataExporterContext ctx, string message) private bool HasPermission(DataExporterContext ctx) { if (ctx.Request.CustomerId == 0) - ctx.Request.CustomerId = _services.WorkContext.CurrentCustomer.Id; + ctx.Request.CustomerId = _services.WorkContext.CurrentCustomer.Id; // fallback to background task system customer var customer = _customerService.GetCustomerById(ctx.Request.CustomerId); @@ -390,7 +390,7 @@ private IExportDataSegmenterProvider CreateSegmenter(DataExporterContext ctx, in private bool CallProvider(DataExporterContext ctx, string streamId, string method, string path) { if (method != "Execute" && method != "OnExecuted") - throw new SmartException("Unknown export method {0}".FormatInvariant(method.NaIfEmpty())); + throw new SmartException("Unknown export method {0}.".FormatInvariant(method.NaIfEmpty())); try { @@ -417,7 +417,7 @@ private bool CallProvider(DataExporterContext ctx, string streamId, string metho using (_rwLock.GetWriteLock()) using (var fileStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.ReadWrite)) { - ctx.Log.Information("Creating file " + path); + ctx.Log.Information("Creating file {0}.".FormatInvariant(path)); ctx.ExecuteContext.DataStream.CopyTo(fileStream); } @@ -427,7 +427,7 @@ private bool CallProvider(DataExporterContext ctx, string streamId, string metho catch (Exception exception) { ctx.ExecuteContext.Abort = DataExchangeAbortion.Hard; - ctx.Log.Error("The provider failed at the {0} method: {1}".FormatInvariant(method, exception.ToAllMessages()), exception); + ctx.Log.Error("The provider failed at the {0} method: {1}.".FormatInvariant(method, exception.ToAllMessages()), exception); ctx.Result.LastError = exception.ToString(); } finally @@ -986,12 +986,12 @@ private void ExportCoreInner(DataExporterContext ctx, Store store) { if (segmenter == null) { - throw new SmartException("Unsupported entity type '{0}'".FormatInvariant(ctx.Request.Provider.Value.EntityType.ToString())); + throw new SmartException("Unsupported entity type '{0}'.".FormatInvariant(ctx.Request.Provider.Value.EntityType.ToString())); } if (segmenter.TotalRecords <= 0) { - ctx.Log.Information("There are no records to export"); + ctx.Log.Information("There are no records to export."); } while (ctx.ExecuteContext.Abort == DataExchangeAbortion.None && segmenter.HasData) @@ -1014,7 +1014,7 @@ private void ExportCoreInner(DataExporterContext ctx, Store store) if (CallProvider(ctx, null, "Execute", path)) { - ctx.Log.Information("Provider reports {0} successfully exported record(s)".FormatInvariant(ctx.ExecuteContext.RecordsSucceeded)); + ctx.Log.Information("Provider reports {0} successfully exported record(s).".FormatInvariant(ctx.ExecuteContext.RecordsSucceeded)); // create info for deployment list in profile edit if (ctx.IsFileBasedExport) @@ -1030,10 +1030,10 @@ private void ExportCoreInner(DataExporterContext ctx, Store store) ctx.EntityIdsPerSegment.Clear(); if (ctx.ExecuteContext.IsMaxFailures) - ctx.Log.Warning("Export aborted. The maximum number of failures has been reached"); + ctx.Log.Warning("Export aborted. The maximum number of failures has been reached."); if (ctx.CancellationToken.IsCancellationRequested) - ctx.Log.Warning("Export aborted. A cancellation has been requested"); + ctx.Log.Warning("Export aborted. A cancellation has been requested."); DetachAllEntitiesAndClear(ctx); } @@ -1072,21 +1072,21 @@ private void ExportCoreOuter(DataExporterContext ctx) { try { + ctx.Log = logger; + ctx.ExecuteContext.Log = logger; + ctx.ProgressInfo = T("Admin.DataExchange.Export.ProgressInfo"); + if (!ctx.Request.Provider.IsValid()) - throw new SmartException("Export aborted because the export provider is not valid"); + throw new SmartException("Export aborted because the export provider is not valid."); if (!HasPermission(ctx)) - throw new SmartException("You do not have permission to perform the selected export"); + throw new SmartException("You do not have permission to perform the selected export."); foreach (var item in ctx.Request.CustomData) { ctx.ExecuteContext.CustomProperties.Add(item.Key, item.Value); } - ctx.Log = logger; - ctx.ExecuteContext.Log = logger; - ctx.ProgressInfo = T("Admin.DataExchange.Export.ProgressInfo"); - if (ctx.Request.Profile.ProviderConfigData.HasValue()) { var configInfo = ctx.Request.Provider.Value.ConfigurationInfo; @@ -1203,11 +1203,11 @@ private void ExportCoreOuter(DataExporterContext ctx) ctx.ProductTemplates.Clear(); ctx.Countries.Clear(); ctx.Languages.Clear(); - ctx.Stores.Clear(); ctx.QuantityUnits.Clear(); ctx.DeliveryTimes.Clear(); ctx.CategoryPathes.Clear(); ctx.Categories.Clear(); + ctx.Stores.Clear(); ctx.Request.CustomData.Clear(); diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/DataImportTask.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/DataImportTask.cs index 51afd08d85..253bd10b6f 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Import/DataImportTask.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/DataImportTask.cs @@ -22,13 +22,17 @@ public void Execute(TaskExecutionContext ctx) var profile = _importProfileService.GetImportProfileById(profileId); var request = new DataImportRequest(profile); - request.CustomerId = ctx.Parameters["CurrentCustomerId"].ToInt(); // do not use built-in background tasks customer request.ProgressValueSetter = delegate (int val, int max, string msg) { ctx.SetProgress(val, max, msg, true); }; + if (ctx.Parameters.ContainsKey("CurrentCustomerId")) + { + request.CustomerId = ctx.Parameters["CurrentCustomerId"].ToInt(); // do not use built-in background tasks customer + } + _importer.Import(request, ctx.CancellationToken); } } diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/DataImporter.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/DataImporter.cs index b2ff901499..52aaf0b992 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Import/DataImporter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/DataImporter.cs @@ -1,44 +1,105 @@ using System; using System.IO; +using System.Linq; using System.Text; using System.Threading; using SmartStore.Core; using SmartStore.Core.Data; +using SmartStore.Core.Domain.Catalog; using SmartStore.Core.Domain.DataExchange; using SmartStore.Core.Domain.Messages; +using SmartStore.Core.Domain.Seo; using SmartStore.Core.Localization; using SmartStore.Core.Logging; +using SmartStore.Services.Catalog; +using SmartStore.Services.Catalog.Importer; using SmartStore.Services.Customers; using SmartStore.Services.DataExchange.Csv; using SmartStore.Services.DataExchange.Import.Internal; +using SmartStore.Services.Localization; +using SmartStore.Services.Media; using SmartStore.Services.Messages.Importer; using SmartStore.Services.Security; +using SmartStore.Services.Seo; +using SmartStore.Services.Stores; using SmartStore.Utilities; namespace SmartStore.Services.DataExchange.Import { public partial class DataImporter : IDataImporter { + #region Dependencies + private readonly ICommonServices _services; private readonly ICustomerService _customerService; + private readonly Lazy> _subscriptionRepository; + private readonly Lazy> _productPictureRepository; + private readonly Lazy> _productManufacturerRepository; + private readonly Lazy> _productCategoryRepository; + private readonly Lazy> _urlRecordRepository; + private readonly Lazy> _productRepository; + + private readonly Lazy _languageService; + private readonly Lazy _localizedEntityService; + private readonly Lazy _pictureService; + private readonly Lazy _manufacturerService; + private readonly Lazy _categoryService; + private readonly Lazy _productService; + private readonly Lazy _urlRecordService; + private readonly Lazy _storeMappingService; + + private readonly Lazy _seoSettings; public DataImporter( ICommonServices services, ICustomerService customerService, - Lazy> subscriptionRepository) + Lazy> subscriptionRepository, + Lazy> productPictureRepository, + Lazy> productManufacturerRepository, + Lazy> productCategoryRepository, + Lazy> urlRecordRepository, + Lazy> productRepository, + Lazy languageService, + Lazy localizedEntityService, + Lazy pictureService, + Lazy manufacturerService, + Lazy categoryService, + Lazy productService, + Lazy urlRecordService, + Lazy storeMappingService, + Lazy seoSettings) { _services = services; _customerService = customerService; _subscriptionRepository = subscriptionRepository; + _productPictureRepository = productPictureRepository; + _productManufacturerRepository = productManufacturerRepository; + _productCategoryRepository = productCategoryRepository; + _urlRecordRepository = urlRecordRepository; + _productRepository = productRepository; + _languageService = languageService; + _localizedEntityService = localizedEntityService; + _pictureService = pictureService; + _manufacturerService = manufacturerService; + _categoryService = categoryService; + _productService = productService; + _urlRecordService = urlRecordService; + _storeMappingService = storeMappingService; + _seoSettings = seoSettings; T = NullLocalizer.Instance; } + #endregion + public Localizer T { get; set; } private bool HasPermission(DataImporterContext ctx) { + if (ctx.Request.CustomerId == 0) + ctx.Request.CustomerId = _services.WorkContext.CurrentCustomer.Id; // fallback to background task system customer + var customer = _customerService.GetCustomerById(ctx.Request.CustomerId); if (ctx.Request.Profile.EntityType == ImportEntityType.Product) @@ -53,8 +114,52 @@ private bool HasPermission(DataImporterContext ctx) return true; } + private void LogResult(DataImporterContext ctx) + { + var result = ctx.ExecuteContext.Result; + var sb = new StringBuilder(); + + sb.AppendLine(); + sb.AppendFormat("Started:\t\t\t{0}\r\n", result.StartDateUtc.ToLocalTime()); + sb.AppendFormat("Finished:\t\t\t{0}\r\n", result.EndDateUtc.ToLocalTime()); + sb.AppendFormat("Duration:\t\t\t{0}\r\n", (result.EndDateUtc - result.StartDateUtc).ToString("g")); + sb.AppendLine(); + sb.AppendFormat("Total rows:\t\t\t{0}\r\n", result.TotalRecords); + sb.AppendFormat("Rows processed:\t\t{0}\r\n", result.AffectedRecords); + sb.AppendFormat("Records imported:\t{0}\r\n", result.NewRecords); + sb.AppendFormat("Records updated:\t{0}\r\n", result.ModifiedRecords); + sb.AppendLine(); + sb.AppendFormat("Warnings:\t\t\t{0}\r\n", result.Messages.Count(x => x.MessageType == ImportMessageType.Warning)); + sb.AppendFormat("Errors:\t\t\t\t{0}", result.Messages.Count(x => x.MessageType == ImportMessageType.Error)); + + ctx.Log.Information(sb.ToString()); + + foreach (var message in result.Messages) + { + string prefix = null; + + if (message.AffectedItem != null) + prefix.Grow("Pos: " + (message.AffectedItem.Position + 1).ToString(), ", "); + + if (message.AffectedField.HasValue()) + prefix.Grow("Field: " + message.AffectedField, ", "); + + if (prefix.HasValue()) + message.Message = "[{0}] {1}".FormatInvariant(prefix, message.Message); + + if (message.MessageType == ImportMessageType.Error) + ctx.Log.Error(message.Message); + else if (message.MessageType == ImportMessageType.Warning) + ctx.Log.Warning(message.Message); + else + ctx.Log.Information(message.Message); + } + } + private void ImportCoreInner(DataImporterContext ctx, string filePath) { + ctx.ExecuteContext.Result.Clear(); + { var logHead = new StringBuilder(); logHead.AppendLine(); @@ -71,7 +176,7 @@ private void ImportCoreInner(DataImporterContext ctx, string filePath) if (!File.Exists(filePath)) { - throw new SmartException("File does not exist {0}".FormatInvariant(filePath)); + throw new SmartException("File does not exist {0}.".FormatInvariant(filePath)); } CsvConfiguration csvConfiguration = null; @@ -86,22 +191,33 @@ private void ImportCoreInner(DataImporterContext ctx, string filePath) if (csvConfiguration == null) { - csvConfiguration = new CsvConfiguration(); + csvConfiguration = CsvConfiguration.ExcelFriendlyConfiguration; + ctx.Log.Warning("No CSV configuration provided for import profile. Fallback to Excel friendly configuration."); } using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) { ctx.ExecuteContext.DataTable = LightweightDataTable.FromFile(Path.GetFileName(filePath), stream, stream.Length, csvConfiguration, ctx.Request.Profile.Skip, take); - ctx.Importer.Execute(ctx.ExecuteContext); + try + { + ctx.Importer.Execute(ctx.ExecuteContext); + } + catch (Exception exception) + { + ctx.ExecuteContext.Abort = DataExchangeAbortion.Hard; + ctx.Log.Error("The importer failed: {0}.".FormatInvariant(exception.ToAllMessages()), exception); + } - ctx.Log.Information("Importer reports {0} added and {1} updated record(s)".FormatInvariant(ctx.ExecuteContext.RecordsAdded, ctx.ExecuteContext.RecordsUpdated)); + ctx.ExecuteContext.Result.EndDateUtc = DateTime.UtcNow; if (ctx.ExecuteContext.IsMaxFailures) - ctx.Log.Warning("Export aborted. The maximum number of failures has been reached"); + ctx.Log.Warning("Import aborted. The maximum number of failures has been reached."); if (ctx.CancellationToken.IsCancellationRequested) - ctx.Log.Warning("Import aborted. A cancellation has been requested"); + ctx.Log.Warning("Import aborted. A cancellation has been requested."); + + LogResult(ctx); } } @@ -122,29 +238,46 @@ private void ImportCoreOuter(DataImporterContext ctx) try { ctx.Log = logger; - ctx.ExecuteContext.Log = logger; var files = ctx.Request.Profile.GetImportFiles(); if (files.Count == 0) - throw new SmartException("No files to import found"); + throw new SmartException("No files to import found."); if (!HasPermission(ctx)) - throw new SmartException("You do not have permission to perform the selected import"); + throw new SmartException("You do not have permission to perform the selected import."); if (ctx.Request.Profile.EntityType == ImportEntityType.Product) - { + { + ctx.Importer = new ProductImporter( + _productPictureRepository.Value, + _productManufacturerRepository.Value, + _productCategoryRepository.Value, + _urlRecordRepository.Value, + _productRepository.Value, + _services, + _languageService.Value, + _localizedEntityService.Value, + _pictureService.Value, + _manufacturerService.Value, + _categoryService.Value, + _productService.Value, + _urlRecordService.Value, + _storeMappingService.Value, + _seoSettings.Value); } else if (ctx.Request.Profile.EntityType == ImportEntityType.Customer) { } else if (ctx.Request.Profile.EntityType == ImportEntityType.NewsLetterSubscription) { - ctx.Importer = new NewsLetterSubscriptionImporter(_services, _subscriptionRepository.Value); + ctx.Importer = new NewsLetterSubscriptionImporter( + _services, + _subscriptionRepository.Value); } else { - throw new SmartException("Unsupported entity type {0}".FormatInvariant(ctx.Request.Profile.EntityType.ToString())); + throw new SmartException("Unsupported entity type {0}.".FormatInvariant(ctx.Request.Profile.EntityType.ToString())); } files.ForEach(x => ImportCoreInner(ctx, x)); diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/IEntityImporter.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/IEntityImporter.cs index 2d0bb6a082..051a95132d 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Import/IEntityImporter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/IEntityImporter.cs @@ -1,9 +1,8 @@ using System; +using System.Linq; using System.Collections.Generic; using System.Threading; -using SmartStore.Core.Domain.Customers; using SmartStore.Core.Domain.DataExchange; -using SmartStore.Core.Logging; namespace SmartStore.Services.DataExchange.Import { @@ -32,10 +31,9 @@ public ImportExecuteContext( CustomerId = customerId; CustomProperties = new Dictionary(); + Result = new ImportResult(); } - public ILogger Log { get; internal set; } - public IDataTable DataTable { get; internal set; } public int CustomerId { get; private set; } @@ -45,9 +43,7 @@ public ImportExecuteContext( /// public Dictionary CustomProperties { get; private set; } - public int RecordsAdded { get; set; } - public int RecordsUpdated { get; set; } - public int RecordsFailed { get; set; } + public ImportResult Result { get; set; } public DataExchangeAbortion Abort { @@ -66,18 +62,10 @@ public DataExchangeAbortion Abort public bool IsMaxFailures { - get { return RecordsFailed > 11; } - } - - /// - /// Processes an exception that occurred while importing a record - /// - /// Exception - public void RecordException(Exception exception, string id) - { - ++RecordsFailed; - - Log.Error("Error while processing record with id {0}: {1}".FormatInvariant(id, exception.ToAllMessages()), exception); + get + { + return Result.Messages.Count(x => x.MessageType == ImportMessageType.Error) > 11; + } } public void SetProgress(int value, int maximum) diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportResult.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportResult.cs index 731a12861b..7e52d3948e 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportResult.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportResult.cs @@ -11,7 +11,17 @@ public class ImportResult public ImportResult() { this.Messages = new List(); - this.StartDateUtc = DateTime.UtcNow; + Clear(); + } + + public void Clear() + { + Messages.Clear(); + StartDateUtc = EndDateUtc = DateTime.UtcNow; + TotalRecords = 0; + NewRecords = 0; + ModifiedRecords = 0; + Cancelled = false; } public DateTime StartDateUtc @@ -72,14 +82,6 @@ public ImportMessage AddError(string message, ImportRowInfo affectedRow = null, public ImportMessage AddError(Exception exception, int? affectedBatch = null, string stage = null) { - var ex = exception; - while (true) - { - if (ex.InnerException == null) - break; - ex = ex.InnerException; - } - var prefix = new List(); if (affectedBatch.HasValue) { @@ -96,7 +98,7 @@ public ImportMessage AddError(Exception exception, int? affectedBatch = null, st msg = "[{0}] ".FormatCurrent(String.Join(", ", prefix)); } - msg += ex.Message; + msg += exception.ToAllMessages(); return this.AddMessage(msg, ImportMessageType.Error); } diff --git a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporterContext.cs b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporterContext.cs index c3960e8bd0..f909b93678 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporterContext.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Internal/DataExporterContext.cs @@ -29,6 +29,10 @@ public DataExporterContext( Categories = new Dictionary(); CategoryPathes = new Dictionary(); + DeliveryTimes = new Dictionary(); + QuantityUnits = new Dictionary(); + Stores = new Dictionary(); + Languages = new Dictionary(); Countries = new Dictionary(); ProductTemplates = new Dictionary(); NewsletterSubscriptions = new HashSet(); diff --git a/src/Libraries/SmartStore.Services/Messages/Importer/NewsLetterSubscriptionImporter.cs b/src/Libraries/SmartStore.Services/Messages/Importer/NewsLetterSubscriptionImporter.cs index 8c0b0abdf2..9cf6be74ac 100644 --- a/src/Libraries/SmartStore.Services/Messages/Importer/NewsLetterSubscriptionImporter.cs +++ b/src/Libraries/SmartStore.Services/Messages/Importer/NewsLetterSubscriptionImporter.cs @@ -5,7 +5,6 @@ using SmartStore.Core.Data; using SmartStore.Core.Domain.DataExchange; using SmartStore.Core.Domain.Messages; -using SmartStore.Core.Logging; using SmartStore.Services.DataExchange.Import; namespace SmartStore.Services.Messages.Importer @@ -36,6 +35,8 @@ public void Execute(ImportExecuteContext context) var segmenter = new ImportDataSegmenter(context.DataTable); segmenter.Culture = CultureInfo.CurrentCulture; + context.Result.TotalRecords = segmenter.TotalRows; + while (context.Abort == DataExchangeAbortion.None && segmenter.ReadNextBatch()) { var batch = segmenter.CurrentBatch; @@ -46,13 +47,9 @@ public void Execute(ImportExecuteContext context) foreach (var row in batch) { - string id = null; - try { var email = row.GetDataValue("Email"); - id = email; - var active = row.GetDataValue("Active"); var storeId = row.GetDataValue("StoreId"); @@ -61,19 +58,19 @@ public void Execute(ImportExecuteContext context) if (email.IsEmpty()) { - context.Log.Warning("Skipped empty email address".FormatInvariant(email)); + context.Result.AddWarning("Skipped empty email address", row.GetRowInfo(), "Email"); continue; } if (email.Length > 255) { - context.Log.Warning("Skipped email address '{0}' because it exceeds the maximum allowed length of 255".FormatInvariant(email)); + context.Result.AddWarning("Skipped email address '{0}'. It exceeds the maximum allowed length of 255".FormatInvariant(email), row.GetRowInfo(), "Email"); continue; } if (!email.IsEmail()) { - context.Log.Warning("Skipped invalid email address '{0}'".FormatInvariant(email)); + context.Result.AddWarning("Skipped invalid email address '{0}'".FormatInvariant(email), row.GetRowInfo(), "Email"); continue; } @@ -93,14 +90,14 @@ public void Execute(ImportExecuteContext context) }; toAdd.Add(subscription); - ++context.RecordsAdded; + ++context.Result.NewRecords; } else { subscription.Active = active; toUpdate.Add(subscription); - ++context.RecordsUpdated; + ++context.Result.ModifiedRecords; } // insert new subscribers @@ -116,7 +113,7 @@ public void Execute(ImportExecuteContext context) } catch (Exception exception) { - context.RecordException(exception, id.NaIfEmpty()); + context.Result.AddError(exception.ToAllMessages(), row.GetRowInfo()); } } } diff --git a/src/Libraries/SmartStore.Services/SmartStore.Services.csproj b/src/Libraries/SmartStore.Services/SmartStore.Services.csproj index 350544f611..a3b6819b57 100644 --- a/src/Libraries/SmartStore.Services/SmartStore.Services.csproj +++ b/src/Libraries/SmartStore.Services/SmartStore.Services.csproj @@ -165,6 +165,7 @@ Properties\AssemblyVersionInfo.cs + diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs index 1a7a72e057..32f84d8afd 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs @@ -975,17 +975,14 @@ public ActionResult PreviewList(GridCommand command, int id, int totalRecords) [HttpPost] public ActionResult Execute(int id, string selectedIds) { - var customer = _services.WorkContext.CurrentCustomer; - - if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageExports, customer)) - return AccessDeniedView(); + // permissions checked internally by DataExporter var profile = _exportService.GetExportProfileById(id); if (profile == null) return RedirectToAction("List"); var taskParams = new Dictionary(); - taskParams.Add("CurrentCustomerId", customer.Id.ToString()); + taskParams.Add("CurrentCustomerId", _services.WorkContext.CurrentCustomer.Id.ToString()); if (selectedIds.HasValue()) taskParams.Add("SelectedIds", selectedIds); diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs index 604f0c53b0..4d57685583 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs @@ -307,17 +307,14 @@ public JsonResult FileUpload(int id) [HttpPost] public ActionResult Execute(int id) { - var customer = _services.WorkContext.CurrentCustomer; - - if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageImports, customer)) - return AccessDeniedView(); + // permissions checked internally by DataImporter var profile = _importService.GetImportProfileById(id); if (profile == null) return RedirectToAction("List"); var taskParams = new Dictionary(); - taskParams.Add("CurrentCustomerId", customer.Id.ToString()); + taskParams.Add("CurrentCustomerId", _services.WorkContext.CurrentCustomer.Id.ToString()); _taskScheduler.RunSingleTask(profile.SchedulingTaskId, taskParams); From ab58896c4be73c9eaece7abfc3bc9a9a7874ede4 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Tue, 15 Dec 2015 17:34:22 +0100 Subject: [PATCH 087/626] It's better to have a file type field for import profiles --- .../Domain/DataExchange/ImportEnums.cs | 6 + .../Domain/DataExchange/ImportProfile.cs | 19 ++- .../Mapping/DataExchange/ImportProfileMap.cs | 2 +- .../201512111134591_ImportFramework.resx | 126 ------------------ ...1512151526290_ImportFramework.Designer.cs} | 2 +- ....cs => 201512151526290_ImportFramework.cs} | 11 +- .../201512151526290_ImportFramework.resx | 126 ++++++++++++++++++ .../SmartStore.Data/SmartStore.Data.csproj | 10 +- .../DataExchange/Import/ImportExtensions.cs | 16 +-- .../Import/ImportProfileService.cs | 7 +- .../Controllers/ImportController.cs | 61 ++++----- .../Models/DataExchange/ImportProfileModel.cs | 5 +- .../Views/Import/_CreateOrUpdate.cshtml | 13 +- .../Views/Import/_ImportFileList.cshtml | 9 +- 14 files changed, 224 insertions(+), 189 deletions(-) delete mode 100644 src/Libraries/SmartStore.Data/Migrations/201512111134591_ImportFramework.resx rename src/Libraries/SmartStore.Data/Migrations/{201512111134591_ImportFramework.Designer.cs => 201512151526290_ImportFramework.Designer.cs} (92%) rename src/Libraries/SmartStore.Data/Migrations/{201512111134591_ImportFramework.cs => 201512151526290_ImportFramework.cs} (92%) create mode 100644 src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.resx diff --git a/src/Libraries/SmartStore.Core/Domain/DataExchange/ImportEnums.cs b/src/Libraries/SmartStore.Core/Domain/DataExchange/ImportEnums.cs index 498c39b3d2..eb993124dc 100644 --- a/src/Libraries/SmartStore.Core/Domain/DataExchange/ImportEnums.cs +++ b/src/Libraries/SmartStore.Core/Domain/DataExchange/ImportEnums.cs @@ -9,4 +9,10 @@ public enum ImportEntityType Customer, NewsLetterSubscription } + + public enum ImportFileType + { + CSV = 0, + XLSX + } } diff --git a/src/Libraries/SmartStore.Core/Domain/DataExchange/ImportProfile.cs b/src/Libraries/SmartStore.Core/Domain/DataExchange/ImportProfile.cs index 2654192757..73e94b5c72 100644 --- a/src/Libraries/SmartStore.Core/Domain/DataExchange/ImportProfile.cs +++ b/src/Libraries/SmartStore.Core/Domain/DataExchange/ImportProfile.cs @@ -16,9 +16,24 @@ public class ImportProfile : BaseEntity public string FolderName { get; set; } /// - /// The name of the initially uploaded import file + /// The identifier of the file type /// - public string FileName { get; set; } + public int FileTypeId { get; set; } + + /// + /// The file type + /// + public ImportFileType FileType + { + get + { + return (ImportFileType)FileTypeId; + } + set + { + FileTypeId = (int)value; + } + } /// /// The identifier of the entity type diff --git a/src/Libraries/SmartStore.Data/Mapping/DataExchange/ImportProfileMap.cs b/src/Libraries/SmartStore.Data/Mapping/DataExchange/ImportProfileMap.cs index 9b0efcac9d..4cb2485f9e 100644 --- a/src/Libraries/SmartStore.Data/Mapping/DataExchange/ImportProfileMap.cs +++ b/src/Libraries/SmartStore.Data/Mapping/DataExchange/ImportProfileMap.cs @@ -12,10 +12,10 @@ public ImportProfileMap() this.Property(x => x.Name).IsRequired().HasMaxLength(100); this.Property(x => x.FolderName).IsRequired().HasMaxLength(100); - this.Property(x => x.FileName).IsRequired().HasMaxLength(400); this.Property(x => x.FileTypeConfiguration).IsMaxLength(); this.Property(x => x.ColumnMapping).IsMaxLength(); + this.Ignore(x => x.FileType); this.Ignore(x => x.EntityType); this.HasRequired(x => x.ScheduleTask) diff --git a/src/Libraries/SmartStore.Data/Migrations/201512111134591_ImportFramework.resx b/src/Libraries/SmartStore.Data/Migrations/201512111134591_ImportFramework.resx deleted file mode 100644 index 1fea63c233..0000000000 --- a/src/Libraries/SmartStore.Data/Migrations/201512111134591_ImportFramework.resx +++ /dev/null @@ -1,126 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 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 - - - dbo - - \ No newline at end of file diff --git a/src/Libraries/SmartStore.Data/Migrations/201512111134591_ImportFramework.Designer.cs b/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.Designer.cs similarity index 92% rename from src/Libraries/SmartStore.Data/Migrations/201512111134591_ImportFramework.Designer.cs rename to src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.Designer.cs index 1d43defd3f..a112acac53 100644 --- a/src/Libraries/SmartStore.Data/Migrations/201512111134591_ImportFramework.Designer.cs +++ b/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.Designer.cs @@ -13,7 +13,7 @@ public sealed partial class ImportFramework : IMigrationMetadata string IMigrationMetadata.Id { - get { return "201512111134591_ImportFramework"; } + get { return "201512151526290_ImportFramework"; } } string IMigrationMetadata.Source diff --git a/src/Libraries/SmartStore.Data/Migrations/201512111134591_ImportFramework.cs b/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs similarity index 92% rename from src/Libraries/SmartStore.Data/Migrations/201512111134591_ImportFramework.cs rename to src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs index f31939779d..b2b7a42d00 100644 --- a/src/Libraries/SmartStore.Data/Migrations/201512111134591_ImportFramework.cs +++ b/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs @@ -16,7 +16,7 @@ public override void Up() Id = c.Int(nullable: false, identity: true), Name = c.String(nullable: false, maxLength: 100), FolderName = c.String(nullable: false, maxLength: 100), - FileName = c.String(nullable: false, maxLength: 400), + FileTypeId = c.Int(nullable: false), EntityTypeId = c.Int(nullable: false), Enabled = c.Boolean(nullable: false), Skip = c.Int(nullable: false), @@ -89,6 +89,12 @@ public void MigrateLocaleResources(LocaleResourcesBuilder builder) "Specifies the name of the import profile.", "Legt den Namen des Importprofils fest."); + builder.AddOrUpdate("Admin.DataExchange.Import.FileType", + "File type", + "Dateityp", + "The file type of the import file(s).", + "Der Dateityp der Importdatei(en)."); + builder.AddOrUpdate("Admin.DataExchange.Import.ProgressInfo", "{0} of {1} records processed", "{0} von {1} Datenstzen verarbeitet"); @@ -98,6 +104,9 @@ public void MigrateLocaleResources(LocaleResourcesBuilder builder) builder.AddOrUpdate("Enums.SmartStore.Core.Domain.DataExchange.ImportEntityType.Customer", "Customer", "Kunde"); builder.AddOrUpdate("Enums.SmartStore.Core.Domain.DataExchange.ImportEntityType.NewsLetterSubscription", "Newsletter Subscribers", "Newsletter Abonnenten"); + builder.AddOrUpdate("Enums.SmartStore.Core.Domain.DataExchange.ImportFileType.CSV", "Delimiter separated values (.csv)", "Trennzeichen getrennte Werte (.csv)"); + builder.AddOrUpdate("Enums.SmartStore.Core.Domain.DataExchange.ImportFileType.XLSX", "Excel (.xlsx)", "Excel (.xlsx)"); + builder.AddOrUpdate("Admin.DataExchange.Import.FileUpload", "Upload import file...", "Importdatei hochladen..."); diff --git a/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.resx b/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.resx new file mode 100644 index 0000000000..fa9e8cc53c --- /dev/null +++ b/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 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 + + + dbo + + \ No newline at end of file diff --git a/src/Libraries/SmartStore.Data/SmartStore.Data.csproj b/src/Libraries/SmartStore.Data/SmartStore.Data.csproj index f58765ce75..afc16698c0 100644 --- a/src/Libraries/SmartStore.Data/SmartStore.Data.csproj +++ b/src/Libraries/SmartStore.Data/SmartStore.Data.csproj @@ -372,9 +372,9 @@ 201511271019577_ExportFramework3.cs - - - 201512111134591_ImportFramework.cs + + + 201512151526290_ImportFramework.cs @@ -699,8 +699,8 @@ 201511271019577_ExportFramework3.cs - - 201512111134591_ImportFramework.cs + + 201512151526290_ImportFramework.cs diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportExtensions.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportExtensions.cs index 6e96b65fe1..89f576e47a 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportExtensions.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportExtensions.cs @@ -30,22 +30,16 @@ public static string GetImportFolder(this ImportProfile profile, bool content = /// List of file paths public static List GetImportFiles(this ImportProfile profile) { - var result = new List(); - var folder = profile.GetImportFolder(true); + var importFolder = profile.GetImportFolder(true); - if (System.IO.Directory.Exists(folder)) + if (System.IO.Directory.Exists(importFolder)) { - var initialImportFile = Path.Combine(folder, profile.FileName); - - result.Add(initialImportFile); - - result.AddRange(System.IO.Directory.EnumerateFiles(folder, "*", SearchOption.TopDirectoryOnly) - .Where(x => !x.IsCaseInsensitiveEqual(initialImportFile)) + return System.IO.Directory.EnumerateFiles(importFolder, "*", SearchOption.TopDirectoryOnly) .OrderBy(x => x) - .ToList()); + .ToList(); } - return result; + return new List(); } /// diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportProfileService.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportProfileService.cs index 782d9509da..39c0ae708e 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportProfileService.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportProfileService.cs @@ -1,4 +1,5 @@ using System; +using System.IO; using System.Linq; using SmartStore.Core.Data; using SmartStore.Core.Domain; @@ -50,12 +51,16 @@ public virtual ImportProfile InsertImportProfile(string fileName, string name, I var profile = new ImportProfile { Name = name, - FileName = fileName, EntityType = entityType, Enabled = true, SchedulingTaskId = task.Id }; + if (Path.GetExtension(fileName).IsCaseInsensitiveEqual(".xlsx")) + profile.FileType = ImportFileType.XLSX; + else + profile.FileType = ImportFileType.CSV; + profile.FolderName = SeoHelper.GetSeName(name, true, false) .ToValidPath() .Truncate(_dataExchangeSettings.MaxFileNameLength); diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs index 4d57685583..958680a2fa 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs @@ -49,11 +49,9 @@ private void PrepareProfileModel(ImportProfileModel model, ImportProfile profile { if (profile != null) { - var extension = Path.GetExtension(profile.FileName); - model.Id = profile.Id; model.Name = profile.Name; - model.FileName = profile.FileName; + model.FileType = profile.FileType; model.EntityType = profile.EntityType; model.Enabled = profile.Enabled; model.Skip = profile.Skip; @@ -69,7 +67,7 @@ private void PrepareProfileModel(ImportProfileModel model, ImportProfile profile .Select(x => Path.GetFileName(x)) .ToList(); - if (extension.IsCaseInsensitiveEqual(".csv")) + if (profile.FileType == ImportFileType.CSV || profile.FileType == ImportFileType.XLSX) { var converter = new CsvConfigurationConverter(); var config = converter.ConvertFrom(profile.FileTypeConfiguration); @@ -86,6 +84,7 @@ private void PrepareProfileModel(ImportProfileModel model, ImportProfile profile if (forEdit) { model.AvailableEntityTypes = ImportEntityType.Product.ToSelectList(false).ToList(); + model.AvailableFileTypes = ImportFileType.CSV.ToSelectList(false).ToList(); } } @@ -135,19 +134,19 @@ public ActionResult Create(ImportProfileModel model) if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageImports)) return AccessDeniedView(); - var importFile = Path.Combine(FileSystemHelper.TempDir(), model.FileName); + var importFile = Path.Combine(FileSystemHelper.TempDir(), model.TempFileName.EmptyNull()); - if (model.FileName.IsEmpty() || !System.IO.File.Exists(importFile)) + if (!System.IO.File.Exists(importFile)) { ModelState.AddModelError("", T("Admin.DataExchange.Import.MissingImportFile")); } else if (ModelState.IsValid) { - var profile = _importService.InsertImportProfile(model.FileName, model.Name, model.EntityType); + var profile = _importService.InsertImportProfile(model.TempFileName, model.Name, model.EntityType); if (profile != null && profile.Id != 0) { - var importFileDestination = Path.Combine(profile.GetImportFolder(true, true), model.FileName); + var importFileDestination = Path.Combine(profile.GetImportFolder(true, true), model.TempFileName); FileSystemHelper.Copy(importFile, importFileDestination, true, true); @@ -187,15 +186,13 @@ public ActionResult Edit(ImportProfileModel model, bool continueEditing, FormCol if (ModelState.IsValid) { - var extension = Path.GetExtension(profile.FileName); - profile.Name = model.Name; profile.EntityType = model.EntityType; profile.Enabled = model.Enabled; profile.Skip = model.Skip; profile.Take = model.Take; - if (extension.IsCaseInsensitiveEqual(".csv") && model.CsvConfiguration != null) + if (profile.FileType == ImportFileType.CSV || profile.FileType == ImportFileType.XLSX) { CsvConfiguration config = model.CsvConfiguration.Clone(); @@ -268,27 +265,27 @@ public JsonResult FileUpload(int id) var profile = _importService.GetImportProfileById(id); if (profile != null) { - var extension = Path.GetExtension(profile.FileName); - - if (postedFile.FileExtension.IsCaseInsensitiveEqual(extension)) - { - var folder = profile.GetImportFolder(true, true); - var destFile = Path.Combine(folder, Path.GetFileName(postedFile.FileName)); - - success = postedFile.Stream.ToFile(destFile); - - if (success) - { - var model = new ImportProfileModel(); - PrepareProfileModel(model, profile, false); - - fileList = this.RenderPartialViewToString("_ImportFileList", model); - } - } - else - { - NotifyError(T("Admin.Common.FileTypeMustEqual", extension.Substring(1).ToUpper())); - } + //var extension = Path.GetExtension(profile.FileType); + + //if (postedFile.FileExtension.IsCaseInsensitiveEqual(extension)) + //{ + // var folder = profile.GetImportFolder(true, true); + // var destFile = Path.Combine(folder, Path.GetFileName(postedFile.FileName)); + + // success = postedFile.Stream.ToFile(destFile); + + // if (success) + // { + // var model = new ImportProfileModel(); + // PrepareProfileModel(model, profile, false); + + // fileList = this.RenderPartialViewToString("_ImportFileList", model); + // } + //} + //else + //{ + // NotifyError(T("Admin.Common.FileTypeMustEqual", extension.Substring(1).ToUpper())); + //} } } } diff --git a/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ImportProfileModel.cs b/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ImportProfileModel.cs index 0190256589..76cc11caff 100644 --- a/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ImportProfileModel.cs +++ b/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ImportProfileModel.cs @@ -15,7 +15,9 @@ public partial class ImportProfileModel : EntityModelBase [SmartResourceDisplayName("Admin.DataExchange.Import.Name")] public string Name { get; set; } - public string FileName { get; set; } + [SmartResourceDisplayName("Admin.DataExchange.Import.FileType")] + public ImportFileType FileType { get; set; } + public List AvailableFileTypes { get; set; } [SmartResourceDisplayName("Admin.Common.ImportFiles")] public List ExistingFileNames { get; set; } @@ -42,6 +44,7 @@ public partial class ImportProfileModel : EntityModelBase public ScheduleTaskModel TaskModel { get; set; } public bool LogFileExists { get; set; } + public string TempFileName { get; set; } public CsvConfigurationModel CsvConfiguration { get; set; } } diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Import/_CreateOrUpdate.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Import/_CreateOrUpdate.cshtml index e1bc7577bc..59d92a5c9d 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Import/_CreateOrUpdate.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Import/_CreateOrUpdate.cshtml @@ -7,7 +7,7 @@ @Html.ValidationSummary(false) @Html.HiddenFor(model => model.Id) -@Html.HiddenFor(model => model.FileName) +@Html.HiddenFor(model => model.TempFileName) @@ -80,6 +80,15 @@ @if (Model.Id != 0) { + + + +
+ @Html.SmartLabelFor(x => x.FileType) + + @Html.DropDownListFor(x => x.FileType, Model.AvailableFileTypes) + @Html.ValidationMessageFor(x => x.FileType) +
@Html.SmartLabelFor(x => x.Enabled) @@ -132,7 +141,7 @@ $('#ImportFileListContainer').show(); if (!_.isEmpty(data.result.tempFile)) { - $('input[name=FileName]').val(data.result.tempFile); + $('input[name=TempFileName]').val(data.result.tempFile); $('#ImportFileList').html(data.result.tempFile); $('#ImportFileUploadContainer').hide(); // just one initial file to specify the file type } diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Import/_ImportFileList.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Import/_ImportFileList.cshtml index d624b86fdb..be0f5d9703 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Import/_ImportFileList.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Import/_ImportFileList.cshtml @@ -6,11 +6,8 @@ @Html.IconForFileExtension(Path.GetExtension(fileName), false) @fileName - @if(!fileName.IsCaseInsensitiveEqual(Model.FileName)) - { - - } +

} \ No newline at end of file From 5b4354222c00d1329bcfae9078e96fc380dffaeb Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Tue, 15 Dec 2015 17:54:28 +0100 Subject: [PATCH 088/626] Updated web.config. Mime type mapping for woff2 required. --- src/Presentation/SmartStore.Web/Web.config | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Presentation/SmartStore.Web/Web.config b/src/Presentation/SmartStore.Web/Web.config index c1470f69a4..9e60aa9751 100644 --- a/src/Presentation/SmartStore.Web/Web.config +++ b/src/Presentation/SmartStore.Web/Web.config @@ -170,6 +170,7 @@ + From 7971fbc90b91ccd170e88b674639f19ce4921c94 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Tue, 15 Dec 2015 17:54:28 +0100 Subject: [PATCH 089/626] Updated web.config. Mime type mapping for woff2 required. --- src/Presentation/SmartStore.Web/Web.config | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Presentation/SmartStore.Web/Web.config b/src/Presentation/SmartStore.Web/Web.config index c1470f69a4..9e60aa9751 100644 --- a/src/Presentation/SmartStore.Web/Web.config +++ b/src/Presentation/SmartStore.Web/Web.config @@ -170,6 +170,7 @@ + From aa1e6717a394eb63a9ac5ce5d1791c81b6b73399 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Tue, 15 Dec 2015 21:04:18 +0100 Subject: [PATCH 090/626] Removed obsolete Excel import button. Products are now imported through import profiles. --- .../201512151526290_ImportFramework.cs | 15 +- .../Controllers/ProductController.cs | 158 +---------------- .../Administration/Views/Product/List.cshtml | 161 +----------------- 3 files changed, 16 insertions(+), 318 deletions(-) diff --git a/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs b/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs index b2b7a42d00..2bc57f326a 100644 --- a/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs +++ b/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs @@ -178,7 +178,20 @@ public void MigrateLocaleResources(LocaleResourcesBuilder builder) "Admin.DataExchange.Export.Limit", "Admin.Promotions.NewsLetterSubscriptions.ImportEmailsSuccess", "Admin.Common.ImportFromCsv", - "Admin.Common.CsvFile" + "Admin.Common.CsvFile", + + "Admin.Common.ImportFromExcel", + "Admin.Common.ExcelFile", + "Admin.Common.ImportFromExcel.InProgress", + "Admin.Common.ImportFromExcel.LastResultTitle", + "Admin.Common.ImportFromExcel.ProcessedCount", + "Admin.Common.ImportFromExcel.QuickStats", + "Admin.Common.ImportFromExcel.ActiveSince", + "Admin.Common.ImportFromExcel.CancelPrompt", + "Admin.Common.ImportFromExcel.Cancel", + "Admin.Common.ImportFromExcel.Cancelled", + "Admin.Common.ImportFromExcel.DownloadReport", + "Admin.Common.ImportFromExcel.NoReportAvailable" ); } } diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/ProductController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/ProductController.cs index d677730a02..8270ea5cdb 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/ProductController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/ProductController.cs @@ -3,16 +3,12 @@ using System.ComponentModel; using System.Data; using System.Linq; -using System.Text; -using System.Threading; -using System.Threading.Tasks; using System.Web.Mvc; using Autofac; using Newtonsoft.Json; using SmartStore.Admin.Models.Catalog; using SmartStore.Collections; using SmartStore.Core; -using SmartStore.Core.Async; using SmartStore.Core.Data; using SmartStore.Core.Domain.Catalog; using SmartStore.Core.Domain.Common; @@ -22,7 +18,6 @@ using SmartStore.Core.Domain.Orders; using SmartStore.Core.Domain.Seo; using SmartStore.Core.Events; -using SmartStore.Core.Infrastructure; using SmartStore.Core.Logging; using SmartStore.Services; using SmartStore.Services.Catalog; @@ -41,10 +36,10 @@ using SmartStore.Services.Tax; using SmartStore.Web.Framework; using SmartStore.Web.Framework.Controllers; -using Telerik.Web.Mvc; using SmartStore.Web.Framework.Filters; using SmartStore.Web.Framework.Modelling; using SmartStore.Web.Framework.Security; +using Telerik.Web.Mvc; namespace SmartStore.Admin.Controllers { @@ -2793,157 +2788,6 @@ public ActionResult EditProductTag(string btnId, string formId, ProductTagModel #endregion - #region Import - - [HttpPost] - public ActionResult ImportExcel(FormCollection form) - { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); - - try - { - var file = Request.Files["importfile"]; - if (file != null) - { - IDataTable table = null; - - try - { - table = LightweightDataTable.FromPostedFile(file); - } - catch (Exception ex) - { - NotifyError(ex); - return RedirectToAction("List"); - } - - var options = TaskCreationOptions.LongRunning; - var cts = new CancellationTokenSource(); - var scheduler = TaskScheduler.Default; - - var task = AsyncRunner.Run((c, ct) => - { - var progress = new Progress(p => - { - AsyncState.Current.Set(p); - }); - - try - { - AsyncState.Current.SetCancelTokenSource(cts); - var importManager = c.Resolve(); - var result = importManager.ImportProducts(table, ct, progress); - - // Saving the result enables us to show a report for last import. - AsyncState.Current.Set(result, neverExpires: true); - } - catch (AggregateException ae) - { - foreach (var e in ae.Flatten().InnerExceptions) - { - // TBD: do exactly WHAT now?! Logging? Nothing? - // [...] - } - } - finally - { - AsyncState.Current.Remove(); - } - - }, cts.Token, options, scheduler); - - task.Wait(500); - } - else - { - NotifyError(T("Admin.Common.UploadFile")); - return RedirectToAction("List"); - } - - NotifySuccess(T("Admin.Common.ImportFromExcel.InProgress")); - return RedirectToAction("List"); - } - catch (Exception exc) - { - NotifyError(exc); - return RedirectToAction("List"); - } - } - - [HttpPost] - public ActionResult ImportExcelProgress() - { - var progress = AsyncState.Current.Get(); - - //object lastResult = null; - string lastResultSummary = null; - string lastResultClass = ""; - var result = AsyncState.Current.Get(); - if (result != null) - { - var title = _localizationService.GetResource("Admin.Common.ImportFromExcel.LastResultTitle").FormatCurrent( - result.EndDateUtc.ToLocalTime(), - result.Cancelled ? " (" + _localizationService.GetResource("Common.Cancelled").ToLower() + ")" : ""); - var counts = _localizationService.GetResource("Admin.Common.ImportFromExcel.ProcessedCount").FormatCurrent( - result.AffectedRecords, - result.TotalRecords); - var stats = _localizationService.GetResource("Admin.Common.ImportFromExcel.QuickStats").FormatCurrent( - result.NewRecords, - result.ModifiedRecords, - result.Messages.Count(x => x.MessageType == ImportMessageType.Warning), - result.Messages.Count(x => x.MessageType == ImportMessageType.Error)); - - lastResultSummary = "{0} {1} {2}".FormatInvariant(title, counts, stats); - - if (!result.Cancelled) - { - lastResultClass = result.HasErrors ? "alert-error" : "alert-success"; - } - } - - if (progress == null) - { - return Json(new { NoRunningTask = true, LastResultSummary = lastResultSummary, LastResultClass = lastResultClass }, JsonRequestBehavior.DenyGet); - } - - return Json(new { Progress = progress, LastResultSummary = lastResultSummary, LastResultClass = lastResultClass }, JsonRequestBehavior.DenyGet); - } - - public ActionResult ImportExcelCancel() - { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); - - var tcs = AsyncState.Current.GetCancelTokenSource(); - if (tcs != null) - { - tcs.Cancel(); - NotifySuccess(_localizationService.GetResource("Admin.Common.ImportFromExcel.Cancelled")); - } - - return RedirectToAction("List"); - } - - public ActionResult ImportExcelDownloadReport() - { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); - - var result = AsyncState.Current.Get(); - if (result == null) - { - return Content(_localizationService.GetResource("Admin.Common.ImportFromExcel.NoReportAvailable")); - } - - var importManager = EngineContext.Current.Resolve(); - string report = importManager.CreateTextReport(result); - - return File(Encoding.UTF8.GetBytes(report), "text/plain", "excelimport-report-{0}.txt".FormatInvariant(result.StartDateUtc.ToLocalTime())); - } - - #endregion - #region Low stock reports public ActionResult LowStockReport() diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Product/List.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Product/List.cshtml index 3c268ef816..feb7fe9c84 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Product/List.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Product/List.cshtml @@ -1,7 +1,6 @@ @model ProductListModel @using Telerik.Web.Mvc.UI @{ - var trueTemplate = "#if (Published) {# #} #"; var allString = T("Admin.Common.All").Text; ViewBag.Title = T("Admin.Catalog.Products.Manage").Text; @@ -24,10 +23,6 @@  @T("Admin.Common.Delete.Selected") - -  @T("Admin.Common.ImportFromExcel") - - @Html.Widget("admin_button_toolbar_after") @@ -311,158 +306,4 @@ $('#mastercheckbox').attr('checked', numChkBoxes == numChkBoxesChecked && numChkBoxes > 0); } -} -@*import products form*@ -@{Html.SmartStore().Window() - .Name("importexcel-window") - .Title(T("Admin.Common.ImportFromExcel").Text) - .Content(@ - @using (Html.BeginForm("ImportExcel", "Product", FormMethod.Post, new { enctype = "multipart/form-data", @class = "form-horizontal" })) - { -
- -
- -
- -
- -
-
- -
-
-
-
-
- @Html.Raw(T("Admin.Common.ImportFromExcel.ProcessedCount").ToString().FormatInvariant("0", "0")) - @Html.Raw(T("Admin.Common.ImportFromExcel.ActiveSince").ToString().FormatCurrent("")) -
-
- @(Html.Raw(T("Admin.Common.ImportFromExcel.QuickStats").ToString().FormatInvariant( - "0", - "0", - "0", - "0"))) -
-
- } - -
) - .FooterContent(@ - - @T("Common.Close") - ) - .Modal(true) - .Visible(false) - .Render(); -} - - +} \ No newline at end of file From 5b691da05810e2800bf2f4d4814abf55f7294202 Mon Sep 17 00:00:00 2001 From: Murat Cakir Date: Wed, 16 Dec 2015 17:38:47 +0100 Subject: [PATCH 091/626] A new mime type entry in web.config should be removed first --- src/Presentation/SmartStore.Web/Web.config | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Presentation/SmartStore.Web/Web.config b/src/Presentation/SmartStore.Web/Web.config index 9e60aa9751..cd1115ffa2 100644 --- a/src/Presentation/SmartStore.Web/Web.config +++ b/src/Presentation/SmartStore.Web/Web.config @@ -164,13 +164,14 @@ + - + From 1696f4d00fe425c2997eae15120bac6eea6e66b3 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Wed, 16 Dec 2015 17:43:09 +0100 Subject: [PATCH 092/626] Added customer importer --- changelog.md | 1 + .../Common/GenericAttributeService.cs | 79 +++-- .../Common/IGenericAttributeService.cs | 13 +- .../Customers/Importer/CustomerImporter.cs | 333 ++++++++++++++++++ .../DataExchange/ExportXmlHelper.cs | 2 + .../DataExchange/Import/DataImporter.cs | 57 ++- .../DataExchange/Import/IEntityImporter.cs | 7 +- .../Import/Internal/DataImporterContext.cs | 6 +- .../Directory/IStateProvinceService.cs | 20 +- .../Directory/StateProvinceService.cs | 31 +- .../NewsLetterSubscriptionImporter.cs | 1 - .../SmartStore.Services.csproj | 1 + .../Controllers/ImportController.cs | 53 +-- 13 files changed, 509 insertions(+), 95 deletions(-) create mode 100644 src/Libraries/SmartStore.Services/Customers/Importer/CustomerImporter.cs diff --git a/changelog.md b/changelog.md index 4f370dcf36..1c11d670f2 100644 --- a/changelog.md +++ b/changelog.md @@ -28,6 +28,7 @@ * #722 System > SEO Names: Implement editing of an UrlRecord * Admin > System > System Info shows used application memory (RAM) * Added option to make VATIN mandatory during customer registration +* Customer import ### Improvements * (Perf) Implemented static caches for URL aliases and localized properties. Increases app startup and request speed by up to 30%. diff --git a/src/Libraries/SmartStore.Services/Common/GenericAttributeService.cs b/src/Libraries/SmartStore.Services/Common/GenericAttributeService.cs index 4c73f2e7ed..d57222a18a 100644 --- a/src/Libraries/SmartStore.Services/Common/GenericAttributeService.cs +++ b/src/Libraries/SmartStore.Services/Common/GenericAttributeService.cs @@ -209,49 +209,54 @@ public virtual void SaveAttribute(BaseEntity entity, string key, TPro if (entity == null) throw new ArgumentNullException("entity"); - string keyGroup = entity.GetUnproxiedEntityType().Name; + SaveAttribute(entity.Id, key, entity.GetUnproxiedEntityType().Name, value, storeId); + } + + public virtual void SaveAttribute(int entityId, string key, string keyGroup, TPropType value, int storeId = 0) + { + Guard.ArgumentNotZero(entityId, "entityId"); - var props = GetAttributesForEntity(entity.Id, keyGroup) + var props = GetAttributesForEntity(entityId, keyGroup) .Where(x => x.StoreId == storeId) .ToList(); - var prop = props.FirstOrDefault(ga => - ga.Key.Equals(key, StringComparison.InvariantCultureIgnoreCase)); // should be culture invariant + var prop = props.FirstOrDefault(ga => + ga.Key.Equals(key, StringComparison.InvariantCultureIgnoreCase)); // should be culture invariant - string valueStr = value.Convert(); + string valueStr = value.Convert(); - if (prop != null) - { - if (string.IsNullOrWhiteSpace(valueStr)) - { - //delete - DeleteAttribute(prop); - } - else - { - //update - prop.Value = valueStr; - UpdateAttribute(prop); - } - } - else - { - if (!string.IsNullOrWhiteSpace(valueStr)) - { - //insert - prop = new GenericAttribute() - { - EntityId = entity.Id, - Key = key, - KeyGroup = keyGroup, - Value = valueStr, + if (prop != null) + { + if (string.IsNullOrWhiteSpace(valueStr)) + { + //delete + DeleteAttribute(prop); + } + else + { + //update + prop.Value = valueStr; + UpdateAttribute(prop); + } + } + else + { + if (!string.IsNullOrWhiteSpace(valueStr)) + { + //insert + prop = new GenericAttribute + { + EntityId = entityId, + Key = key, + KeyGroup = keyGroup, + Value = valueStr, StoreId = storeId - }; - InsertAttribute(prop); - } - } - } + }; + InsertAttribute(prop); + } + } + } - #endregion - } + #endregion + } } \ No newline at end of file diff --git a/src/Libraries/SmartStore.Services/Common/IGenericAttributeService.cs b/src/Libraries/SmartStore.Services/Common/IGenericAttributeService.cs index cb837a6f74..c584c4ad4c 100644 --- a/src/Libraries/SmartStore.Services/Common/IGenericAttributeService.cs +++ b/src/Libraries/SmartStore.Services/Common/IGenericAttributeService.cs @@ -69,5 +69,16 @@ public partial interface IGenericAttributeService /// Value /// Store identifier; pass 0 if this attribute will be available for all stores void SaveAttribute(BaseEntity entity, string key, TPropType value, int storeId = 0); - } + + /// + /// Save attribute value + /// + /// Property type + /// Entity identifier + /// The key + /// The key group + /// Property type + /// Store identifier; pass 0 if this attribute will be available for all stores + void SaveAttribute(int entityId, string key, string keyGroup, TPropType value, int storeId = 0); + } } \ No newline at end of file diff --git a/src/Libraries/SmartStore.Services/Customers/Importer/CustomerImporter.cs b/src/Libraries/SmartStore.Services/Customers/Importer/CustomerImporter.cs new file mode 100644 index 0000000000..c5204fe8aa --- /dev/null +++ b/src/Libraries/SmartStore.Services/Customers/Importer/CustomerImporter.cs @@ -0,0 +1,333 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using SmartStore.Core.Data; +using SmartStore.Core.Domain.Customers; +using SmartStore.Core.Domain.DataExchange; +using SmartStore.Core.Domain.Forums; +using SmartStore.Core.Events; +using SmartStore.Services.Affiliates; +using SmartStore.Services.Common; +using SmartStore.Services.DataExchange.Import; +using SmartStore.Services.Directory; +using SmartStore.Services.Helpers; +using SmartStore.Services.Security; + +namespace SmartStore.Services.Customers.Importer +{ + public class CustomerImporter : IEntityImporter + { + private const string _attributeKeyGroup = "Customer"; + + private readonly ICommonServices _services; + private readonly IRepository _customerRepository; + private readonly IGenericAttributeService _genericAttributeService; + private readonly ICustomerService _customerService; + private readonly IAffiliateService _affiliateService; + private readonly ICountryService _countryService; + private readonly IStateProvinceService _stateProvinceService; + private readonly CustomerSettings _customerSettings; + private readonly DateTimeSettings _dateTimeSettings; + private readonly ForumSettings _forumSettings; + + public CustomerImporter( + ICommonServices services, + IRepository customerRepository, + IGenericAttributeService genericAttributeService, + ICustomerService customerService, + IAffiliateService affiliateService, + ICountryService countryService, + IStateProvinceService stateProvinceService, + CustomerSettings customerSettings, + DateTimeSettings dateTimeSettings, + ForumSettings forumSettings) + { + _services = services; + _customerRepository = customerRepository; + _genericAttributeService = genericAttributeService; + _customerService = customerService; + _affiliateService = affiliateService; + _countryService = countryService; + _stateProvinceService = stateProvinceService; + _customerSettings = customerSettings; + _dateTimeSettings = dateTimeSettings; + _forumSettings = forumSettings; + } + + private void SaveAttribute(ImportRow row, string key) + { + _genericAttributeService.SaveAttribute(row.Entity.Id, key, _attributeKeyGroup, row.GetDataValue(key)); + } + + private void UpsertRole(ImportRow row, CustomerRole role, string roleSystemName, bool value) + { + if (role != null) + { + var hasRole = row.Entity.CustomerRoles.Any(x => x.SystemName == roleSystemName); + + if (value && !hasRole) + row.Entity.CustomerRoles.Add(role); + else if (!value && hasRole) + row.Entity.CustomerRoles.Remove(role); + } + } + + private int ProcessGenericAttributes(ImportExecuteContext context, + ImportRow[] batch, + List allCountryIds, + List allStateProvinceIds, + List allCustomerNumbers) + { + foreach (var row in batch) + { + SaveAttribute(row, SystemCustomerAttributeNames.FirstName); + SaveAttribute(row, SystemCustomerAttributeNames.LastName); + + if (_dateTimeSettings.AllowCustomersToSetTimeZone) + SaveAttribute(row, SystemCustomerAttributeNames.TimeZoneId); + + if (_customerSettings.GenderEnabled) + SaveAttribute(row, SystemCustomerAttributeNames.Gender); + + if (_customerSettings.DateOfBirthEnabled) + SaveAttribute(row, SystemCustomerAttributeNames.DateOfBirth); + + if (_customerSettings.CompanyEnabled) + SaveAttribute(row, SystemCustomerAttributeNames.Company); + + if (_customerSettings.StreetAddressEnabled) + SaveAttribute(row, SystemCustomerAttributeNames.StreetAddress); + + if (_customerSettings.StreetAddress2Enabled) + SaveAttribute(row, SystemCustomerAttributeNames.StreetAddress2); + + if (_customerSettings.ZipPostalCodeEnabled) + SaveAttribute(row, SystemCustomerAttributeNames.ZipPostalCode); + + if (_customerSettings.CityEnabled) + SaveAttribute(row, SystemCustomerAttributeNames.City); + + if (_customerSettings.CountryEnabled) + SaveAttribute(row, SystemCustomerAttributeNames.CountryId); + + if (_customerSettings.CountryEnabled && _customerSettings.StateProvinceEnabled) + SaveAttribute(row, SystemCustomerAttributeNames.StateProvinceId); + + if (_customerSettings.PhoneEnabled) + SaveAttribute(row, SystemCustomerAttributeNames.Phone); + + if (_customerSettings.FaxEnabled) + SaveAttribute(row, SystemCustomerAttributeNames.Fax); + + if (_customerSettings.AllowCustomersToUploadAvatars) + SaveAttribute(row, SystemCustomerAttributeNames.AvatarPictureId); + + if (_forumSettings.ForumsEnabled) + SaveAttribute(row, SystemCustomerAttributeNames.ForumPostCount); + + if (_forumSettings.SignaturesEnabled) + SaveAttribute(row, SystemCustomerAttributeNames.Signature); + + var countryId = row.GetDataValue("CountryId"); + var stateProvinceId = row.GetDataValue("StateProvinceId"); + + if (countryId != 0 && allCountryIds.Contains(countryId)) + { + _genericAttributeService.SaveAttribute(row.Entity.Id, SystemCustomerAttributeNames.CountryId, _attributeKeyGroup, countryId); + } + + if (stateProvinceId != 0 && allStateProvinceIds.Contains(stateProvinceId)) + { + _genericAttributeService.SaveAttribute(row.Entity.Id, SystemCustomerAttributeNames.StateProvinceId, _attributeKeyGroup, stateProvinceId); + } + + string customerNumber = null; + + if (_customerSettings.CustomerNumberMethod == CustomerNumberMethod.AutomaticallySet) + customerNumber = row.Entity.Id.ToString(); + else + customerNumber = row.GetDataValue("CustomerNumber"); + + if (customerNumber.IsEmpty() || !allCustomerNumbers.Any(x => x.IsCaseInsensitiveEqual(customerNumber))) + { + _genericAttributeService.SaveAttribute(row.Entity.Id, SystemCustomerAttributeNames.CustomerNumber, _attributeKeyGroup, customerNumber); + + if (!customerNumber.IsEmpty()) + allCustomerNumbers.Add(customerNumber); + } + } + + var num = _customerRepository.Context.SaveChanges(); + + return num; + } + + private int ProcessCustomers(ImportExecuteContext context, + ImportRow[] batch, + DateTime utcNow, + List allAffiliateIds, + IList allCustomerRoles) + { + _customerRepository.AutoCommitEnabled = true; + + Customer lastInserted = null; + Customer lastUpdated = null; + + var guestRole = allCustomerRoles.FirstOrDefault(x => x.SystemName == SystemCustomerRoleNames.Guests); + var registeredRole = allCustomerRoles.FirstOrDefault(x => x.SystemName == SystemCustomerRoleNames.Registered); + var adminRole = allCustomerRoles.FirstOrDefault(x => x.SystemName == SystemCustomerRoleNames.Administrators); + var forumModeratorRole = allCustomerRoles.FirstOrDefault(x => x.SystemName == SystemCustomerRoleNames.ForumModerators); + + foreach (var row in batch) + { + object key; + var customerId = 0; + Customer customer = null; + + if (row.DataRow.TryGetValue("Id", out key) && key.ToString().ToInt() > 0) + { + customerId = key.ToString().ToInt(); + customer = _customerService.GetCustomerById(customerId); + } + + if (customer == null && row.DataRow.TryGetValue("CustomerGuid", out key)) + { + customer = _customerService.GetCustomerByGuid(new Guid(key.ToString())); + } + + if (customer == null) + { + customer = new Customer(); + } + else + { + _customerRepository.Context.LoadCollection(customer, (Customer x) => x.CustomerRoles); + } + + var email = row.GetDataValue("Email"); + var affiliateId = row.GetDataValue("AffiliateId"); + var isGuest = row.GetDataValue("IsGuest"); + var isRegistered = row.GetDataValue("IsRegistered"); + var isAdmin = row.GetDataValue("IsAdministrator"); + var isForumModerator = row.GetDataValue("IsForumModerator"); + + row.Initialize(customer, email.HasValue() ? email : customerId.ToString()); + + row.SetProperty(context.Result, customer, (x) => x.CustomerGuid); + row.SetProperty(context.Result, customer, (x) => x.Username); + row.SetProperty(context.Result, customer, (x) => x.Email); + row.SetProperty(context.Result, customer, (x) => x.Password); + row.SetProperty(context.Result, customer, (x) => x.PasswordFormatId); + row.SetProperty(context.Result, customer, (x) => x.PasswordSalt); + row.SetProperty(context.Result, customer, (x) => x.AdminComment); + row.SetProperty(context.Result, customer, (x) => x.IsTaxExempt); + row.SetProperty(context.Result, customer, (x) => x.Active); + row.SetProperty(context.Result, customer, (x) => x.IsSystemAccount); + row.SetProperty(context.Result, customer, (x) => x.SystemName); + row.SetProperty(context.Result, customer, (x) => x.LastIpAddress); + row.SetProperty(context.Result, customer, (x) => x.LastLoginDateUtc); + row.SetProperty(context.Result, customer, (x) => x.LastActivityDateUtc); + + row.SetProperty(context.Result, customer, (x) => x.CreatedOnUtc, utcNow); + row.SetProperty(context.Result, customer, (x) => x.LastActivityDateUtc, utcNow); + + if (affiliateId != 0 && allAffiliateIds.Contains(affiliateId)) + { + row.SetProperty(context.Result, customer, (x) => x.AffiliateId, affiliateId); + } + + UpsertRole(row, guestRole, SystemCustomerRoleNames.Guests, isGuest); + UpsertRole(row, registeredRole, SystemCustomerRoleNames.Registered, isRegistered); + UpsertRole(row, adminRole, SystemCustomerRoleNames.Administrators, isAdmin); + UpsertRole(row, forumModeratorRole, SystemCustomerRoleNames.ForumModerators, isForumModerator); + + if (row.IsTransient) + { + _customerRepository.Insert(customer); + lastInserted = customer; + } + else + { + _customerRepository.Update(customer); + lastUpdated = customer; + } + } + + var num = _customerRepository.Context.SaveChanges(); + + if (lastInserted != null) + _services.EventPublisher.EntityInserted(lastInserted); + if (lastUpdated != null) + _services.EventPublisher.EntityUpdated(lastUpdated); + + return num; + } + + public void Execute(ImportExecuteContext context) + { + var utcNow = DateTime.UtcNow; + var customer = _customerService.GetCustomerById(context.CustomerId); + var allowManagingCustomerRoles = _services.Permissions.Authorize(StandardPermissionProvider.ManageCustomerRoles, customer); + + var allCustomerRoles = _customerService.GetAllCustomerRoles(true); + + var allAffiliateIds = _affiliateService.GetAllAffiliates(true) + .Select(x => x.Id) + .ToList(); + + var allCountryIds = _countryService.GetAllCountries(true) + .Select(x => x.Id) + .ToList(); + + var allStateProvinceIds = _stateProvinceService.GetAllStateProvinces(true) + .Select(x => x.Id) + .ToList(); + + var allCustomerNumbers = _genericAttributeService.GetAttributes(SystemCustomerAttributeNames.CustomerNumber, _attributeKeyGroup) + .Select(x => x.Value) + .ToList(); + + using (var scope = new DbContextScope(ctx: _services.DbContext, autoDetectChanges: false, proxyCreation: false, validateOnSave: false, autoCommit: false)) + { + var segmenter = new ImportDataSegmenter(context.DataTable); + + context.Result.TotalRecords = segmenter.TotalRows; + + while (context.Abort == DataExchangeAbortion.None && segmenter.ReadNextBatch()) + { + var batch = segmenter.CurrentBatch; + + _customerRepository.Context.DetachAll(false); + + context.SetProgress(segmenter.CurrentSegmentFirstRowIndex - 1, segmenter.TotalRows); + + try + { + ProcessCustomers(context, batch, utcNow, allAffiliateIds, allCustomerRoles); + } + catch (Exception exception) + { + context.Result.AddError(exception, segmenter.CurrentSegment, "ProcessCustomers"); + } + + // reduce batch to saved (valid) records. + // No need to perform import operations on errored records. + batch = batch.Where(x => x.Entity != null && !x.IsTransient).ToArray(); + + // update result object + context.Result.NewRecords += batch.Count(x => x.IsNew && !x.IsTransient); + context.Result.ModifiedRecords += batch.Count(x => !x.IsNew && !x.IsTransient); + + try + { + ProcessGenericAttributes(context, batch, allCountryIds, allStateProvinceIds, allCustomerNumbers); + } + catch (Exception exception) + { + context.Result.AddError(exception, segmenter.CurrentSegment, "ProcessGenericAttributes"); + } + } + } + } + } +} diff --git a/src/Libraries/SmartStore.Services/DataExchange/ExportXmlHelper.cs b/src/Libraries/SmartStore.Services/DataExchange/ExportXmlHelper.cs index 425ac57265..6f84b5f064 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/ExportXmlHelper.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/ExportXmlHelper.cs @@ -838,7 +838,9 @@ public void WriteCustomer(dynamic customer, string node) _writer.Write("CustomerGuid", entity.CustomerGuid.ToString()); _writer.Write("Username", entity.Username); _writer.Write("Email", entity.Email); + _writer.Write("Password", entity.Password); _writer.Write("PasswordFormatId", entity.PasswordFormatId.ToString()); + _writer.Write("PasswordSalt", entity.PasswordSalt); _writer.Write("AdminComment", entity.AdminComment); _writer.Write("IsTaxExempt", entity.IsTaxExempt.ToString()); _writer.Write("AffiliateId", entity.AffiliateId.ToString()); diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/DataImporter.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/DataImporter.cs index 52aaf0b992..56906c4b8a 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Import/DataImporter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/DataImporter.cs @@ -6,16 +6,23 @@ using SmartStore.Core; using SmartStore.Core.Data; using SmartStore.Core.Domain.Catalog; +using SmartStore.Core.Domain.Customers; using SmartStore.Core.Domain.DataExchange; +using SmartStore.Core.Domain.Forums; using SmartStore.Core.Domain.Messages; using SmartStore.Core.Domain.Seo; using SmartStore.Core.Localization; using SmartStore.Core.Logging; +using SmartStore.Services.Affiliates; using SmartStore.Services.Catalog; using SmartStore.Services.Catalog.Importer; +using SmartStore.Services.Common; using SmartStore.Services.Customers; +using SmartStore.Services.Customers.Importer; using SmartStore.Services.DataExchange.Csv; using SmartStore.Services.DataExchange.Import.Internal; +using SmartStore.Services.Directory; +using SmartStore.Services.Helpers; using SmartStore.Services.Localization; using SmartStore.Services.Media; using SmartStore.Services.Messages.Importer; @@ -39,6 +46,7 @@ public partial class DataImporter : IDataImporter private readonly Lazy> _productCategoryRepository; private readonly Lazy> _urlRecordRepository; private readonly Lazy> _productRepository; + private readonly Lazy> _customerRepository; private readonly Lazy _languageService; private readonly Lazy _localizedEntityService; @@ -48,8 +56,15 @@ public partial class DataImporter : IDataImporter private readonly Lazy _productService; private readonly Lazy _urlRecordService; private readonly Lazy _storeMappingService; + private readonly Lazy _genericAttributeService; + private readonly Lazy _affiliateService; + private readonly Lazy _countryService; + private readonly Lazy _stateProvinceService; private readonly Lazy _seoSettings; + private readonly Lazy _customerSettings; + private readonly Lazy _dateTimeSettings; + private readonly Lazy _forumSettings; public DataImporter( ICommonServices services, @@ -60,6 +75,7 @@ public DataImporter( Lazy> productCategoryRepository, Lazy> urlRecordRepository, Lazy> productRepository, + Lazy> customerRepository, Lazy languageService, Lazy localizedEntityService, Lazy pictureService, @@ -68,7 +84,14 @@ public DataImporter( Lazy productService, Lazy urlRecordService, Lazy storeMappingService, - Lazy seoSettings) + Lazy genericAttributeService, + Lazy affiliateService, + Lazy countryService, + Lazy stateProvinceService, + Lazy seoSettings, + Lazy customerSettings, + Lazy dateTimeSettings, + Lazy forumSettings) { _services = services; _customerService = customerService; @@ -78,6 +101,8 @@ public DataImporter( _productCategoryRepository = productCategoryRepository; _urlRecordRepository = urlRecordRepository; _productRepository = productRepository; + _customerRepository = customerRepository; + _languageService = languageService; _localizedEntityService = localizedEntityService; _pictureService = pictureService; @@ -86,7 +111,15 @@ public DataImporter( _productService = productService; _urlRecordService = urlRecordService; _storeMappingService = storeMappingService; + _genericAttributeService = genericAttributeService; + _affiliateService = affiliateService; + _countryService = countryService; + _stateProvinceService = stateProvinceService; + _seoSettings = seoSettings; + _customerSettings = customerSettings; + _dateTimeSettings = dateTimeSettings; + _forumSettings = forumSettings; T = NullLocalizer.Instance; } @@ -97,9 +130,6 @@ public DataImporter( private bool HasPermission(DataImporterContext ctx) { - if (ctx.Request.CustomerId == 0) - ctx.Request.CustomerId = _services.WorkContext.CurrentCustomer.Id; // fallback to background task system customer - var customer = _customerService.GetCustomerById(ctx.Request.CustomerId); if (ctx.Request.Profile.EntityType == ImportEntityType.Product) @@ -226,9 +256,6 @@ private void ImportCoreOuter(DataImporterContext ctx) if (ctx.Request.Profile == null || !ctx.Request.Profile.Enabled) return; - if (ctx.Request.CustomerId == 0) - ctx.Request.CustomerId = _services.WorkContext.CurrentCustomer.Id; - var logPath = ctx.Request.Profile.GetImportLogPath(); FileSystemHelper.Delete(logPath); @@ -239,6 +266,11 @@ private void ImportCoreOuter(DataImporterContext ctx) { ctx.Log = logger; + if (ctx.Request.CustomerId == 0) + ctx.Request.CustomerId = _services.WorkContext.CurrentCustomer.Id; // fallback to system background task customer + + ctx.ExecuteContext.CustomerId = ctx.Request.CustomerId; + var files = ctx.Request.Profile.GetImportFiles(); if (files.Count == 0) @@ -268,6 +300,17 @@ private void ImportCoreOuter(DataImporterContext ctx) } else if (ctx.Request.Profile.EntityType == ImportEntityType.Customer) { + ctx.Importer = new CustomerImporter( + _services, + _customerRepository.Value, + _genericAttributeService.Value, + _customerService, + _affiliateService.Value, + _countryService.Value, + _stateProvinceService.Value, + _customerSettings.Value, + _dateTimeSettings.Value, + _forumSettings.Value); } else if (ctx.Request.Profile.EntityType == ImportEntityType.NewsLetterSubscription) { diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/IEntityImporter.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/IEntityImporter.cs index 051a95132d..1772fce95e 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Import/IEntityImporter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/IEntityImporter.cs @@ -1,5 +1,4 @@ -using System; -using System.Linq; +using System.Linq; using System.Collections.Generic; using System.Threading; using SmartStore.Core.Domain.DataExchange; @@ -21,7 +20,6 @@ public class ImportExecuteContext public ImportExecuteContext( CancellationToken cancellation, - int customerId, ProgressValueSetter progressValueSetter, string progressInfo) { @@ -29,14 +27,13 @@ public ImportExecuteContext( _progressValueSetter = progressValueSetter; _progressInfo = progressInfo; - CustomerId = customerId; CustomProperties = new Dictionary(); Result = new ImportResult(); } public IDataTable DataTable { get; internal set; } - public int CustomerId { get; private set; } + public int CustomerId { get; internal set; } /// /// Use this dictionary for any custom data required along the import diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/Internal/DataImporterContext.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/Internal/DataImporterContext.cs index 2a9b3f3db4..41efff1883 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Import/Internal/DataImporterContext.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/Internal/DataImporterContext.cs @@ -13,11 +13,7 @@ public DataImporterContext( Request = request; CancellationToken = cancellationToken; - ExecuteContext = new ImportExecuteContext( - CancellationToken, - Request.CustomerId, - Request.ProgressValueSetter, - progressInfo); + ExecuteContext = new ImportExecuteContext(CancellationToken, Request.ProgressValueSetter, progressInfo); } public DataImportRequest Request { get; private set; } diff --git a/src/Libraries/SmartStore.Services/Directory/IStateProvinceService.cs b/src/Libraries/SmartStore.Services/Directory/IStateProvinceService.cs index 95f0c91c2a..e62ff53527 100644 --- a/src/Libraries/SmartStore.Services/Directory/IStateProvinceService.cs +++ b/src/Libraries/SmartStore.Services/Directory/IStateProvinceService.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using SmartStore.Core.Domain.Directory; namespace SmartStore.Services.Directory @@ -14,12 +15,19 @@ public partial interface IStateProvinceService /// The state/province void DeleteStateProvince(StateProvince stateProvince); - /// - /// Gets a state/province - /// - /// The state/province identifier - /// State/province - StateProvince GetStateProvinceById(int stateProvinceId); + /// + /// Get all states/provinces + /// + /// A value indicating whether to show hidden records + /// + IQueryable GetAllStateProvinces(bool showHidden = false); + + /// + /// Gets a state/province + /// + /// The state/province identifier + /// State/province + StateProvince GetStateProvinceById(int stateProvinceId); /// /// Gets a state/province diff --git a/src/Libraries/SmartStore.Services/Directory/StateProvinceService.cs b/src/Libraries/SmartStore.Services/Directory/StateProvinceService.cs index 27ddf6f5a6..b631dca9e9 100644 --- a/src/Libraries/SmartStore.Services/Directory/StateProvinceService.cs +++ b/src/Libraries/SmartStore.Services/Directory/StateProvinceService.cs @@ -8,10 +8,10 @@ namespace SmartStore.Services.Directory { - /// - /// State province service - /// - public partial class StateProvinceService : IStateProvinceService + /// + /// State province service + /// + public partial class StateProvinceService : IStateProvinceService { #region Constants private const string STATEPROVINCES_ALL_KEY = "SmartStore.stateprovince.all-{0}"; @@ -46,6 +46,7 @@ public StateProvinceService(ICacheManager cacheManager, #endregion #region Methods + /// /// Deletes a state/province /// @@ -63,12 +64,22 @@ public virtual void DeleteStateProvince(StateProvince stateProvince) _eventPublisher.EntityDeleted(stateProvince); } - /// - /// Gets a state/province - /// - /// The state/province identifier - /// State/province - public virtual StateProvince GetStateProvinceById(int stateProvinceId) + public virtual IQueryable GetAllStateProvinces(bool showHidden = false) + { + var query = _stateProvinceRepository.Table; + + if (!showHidden) + query = query.Where(x => x.Published); + + return query; + } + + /// + /// Gets a state/province + /// + /// The state/province identifier + /// State/province + public virtual StateProvince GetStateProvinceById(int stateProvinceId) { if (stateProvinceId == 0) return null; diff --git a/src/Libraries/SmartStore.Services/Messages/Importer/NewsLetterSubscriptionImporter.cs b/src/Libraries/SmartStore.Services/Messages/Importer/NewsLetterSubscriptionImporter.cs index 9cf6be74ac..0037b755f4 100644 --- a/src/Libraries/SmartStore.Services/Messages/Importer/NewsLetterSubscriptionImporter.cs +++ b/src/Libraries/SmartStore.Services/Messages/Importer/NewsLetterSubscriptionImporter.cs @@ -33,7 +33,6 @@ public void Execute(ImportExecuteContext context) using (var scope = new DbContextScope(ctx: _services.DbContext, autoDetectChanges: false, proxyCreation: false, validateOnSave: false, autoCommit: false)) { var segmenter = new ImportDataSegmenter(context.DataTable); - segmenter.Culture = CultureInfo.CurrentCulture; context.Result.TotalRecords = segmenter.TotalRows; diff --git a/src/Libraries/SmartStore.Services/SmartStore.Services.csproj b/src/Libraries/SmartStore.Services/SmartStore.Services.csproj index a3b6819b57..06bf906f25 100644 --- a/src/Libraries/SmartStore.Services/SmartStore.Services.csproj +++ b/src/Libraries/SmartStore.Services/SmartStore.Services.csproj @@ -171,6 +171,7 @@ + diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs index 958680a2fa..112646bb72 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs @@ -242,6 +242,7 @@ public ActionResult DeleteConfirmed(int id) public JsonResult FileUpload(int id) { var success = false; + string error = null; string tempFile = ""; string fileList = ""; @@ -265,39 +266,45 @@ public JsonResult FileUpload(int id) var profile = _importService.GetImportProfileById(id); if (profile != null) { - //var extension = Path.GetExtension(profile.FileType); - - //if (postedFile.FileExtension.IsCaseInsensitiveEqual(extension)) - //{ - // var folder = profile.GetImportFolder(true, true); - // var destFile = Path.Combine(folder, Path.GetFileName(postedFile.FileName)); - - // success = postedFile.Stream.ToFile(destFile); - - // if (success) - // { - // var model = new ImportProfileModel(); - // PrepareProfileModel(model, profile, false); - - // fileList = this.RenderPartialViewToString("_ImportFileList", model); - // } - //} - //else - //{ - // NotifyError(T("Admin.Common.FileTypeMustEqual", extension.Substring(1).ToUpper())); - //} + var files = profile.GetImportFiles(); + if (files.Any()) + { + var extension = Path.GetExtension(files.First()); + + if (!postedFile.FileExtension.IsCaseInsensitiveEqual(extension)) + error = T("Admin.Common.FileTypeMustEqual", extension.Substring(1).ToUpper()); + } + + if (!error.HasValue()) + { + var folder = profile.GetImportFolder(true, true); + var destFile = Path.Combine(folder, Path.GetFileName(postedFile.FileName)); + + success = postedFile.Stream.ToFile(destFile); + + if (success) + { + var model = new ImportProfileModel(); + PrepareProfileModel(model, profile, false); + + fileList = this.RenderPartialViewToString("_ImportFileList", model); + } + } } } } if (!success) - NotifyError(T("Admin.Common.UploadFileFailed")); + error = T("Admin.Common.UploadFileFailed"); } else { - NotifyError(T("Admin.AccessDenied.Description")); + error = T("Admin.AccessDenied.Description"); } + if (error.HasValue()) + NotifyError(error); + return Json(new { success = success, tempFile = tempFile, fileList = fileList }); } From b3b30e84d304866bfbfe832fe737d01b7b680b6c Mon Sep 17 00:00:00 2001 From: Murat Cakir Date: Wed, 16 Dec 2015 17:38:47 +0100 Subject: [PATCH 093/626] A new mime type entry in web.config should be removed first --- src/Presentation/SmartStore.Web/Web.config | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Presentation/SmartStore.Web/Web.config b/src/Presentation/SmartStore.Web/Web.config index 9e60aa9751..cd1115ffa2 100644 --- a/src/Presentation/SmartStore.Web/Web.config +++ b/src/Presentation/SmartStore.Web/Web.config @@ -164,13 +164,14 @@ + - + From 76c03330adb6ae5d2ba08dec573ae0c2e45edac9 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Thu, 17 Dec 2015 10:30:01 +0100 Subject: [PATCH 094/626] Had to touch web.config through IIS to avoid 404 for bundles --- src/Presentation/SmartStore.Web/Web.config | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Presentation/SmartStore.Web/Web.config b/src/Presentation/SmartStore.Web/Web.config index cd1115ffa2..db0da925b3 100644 --- a/src/Presentation/SmartStore.Web/Web.config +++ b/src/Presentation/SmartStore.Web/Web.config @@ -1,4 +1,4 @@ - + @@ -92,7 +92,7 @@ - + From 15b4ddd0000b4ed9bb916a18c189afb105fccead Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Thu, 17 Dec 2015 17:41:44 +0100 Subject: [PATCH 095/626] Testing product import --- .../Catalog/Importer/ProductImporter.cs | 10 +++++----- .../DataExchange/Import/ImportProfileService.cs | 4 +++- .../Administration/Controllers/ImportController.cs | 10 +++++----- .../Administration/Views/Import/_CreateOrUpdate.cshtml | 4 +++- 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/Libraries/SmartStore.Services/Catalog/Importer/ProductImporter.cs b/src/Libraries/SmartStore.Services/Catalog/Importer/ProductImporter.cs index bfd2d5d27d..dd0195f223 100644 --- a/src/Libraries/SmartStore.Services/Catalog/Importer/ProductImporter.cs +++ b/src/Libraries/SmartStore.Services/Catalog/Importer/ProductImporter.cs @@ -361,7 +361,7 @@ private int ProcessSlugs(ImportExecuteContext context, ImportRow[] batc return _rsUrlRecord.Context.SaveChanges(); } - private int ProcessProducts(ImportExecuteContext context, ImportRow[] batch) + private int ProcessProducts(ImportExecuteContext context, ImportRow[] batch, DateTime utcNow) { _rsProduct.AutoCommitEnabled = true; @@ -507,9 +507,9 @@ private int ProcessProducts(ImportExecuteContext context, ImportRow[] b _storeMappingService.SaveStoreMappings(product, storeIds.ToArray()); } - row.SetProperty(context.Result, product, (x) => x.CreatedOnUtc, DateTime.UtcNow); + row.SetProperty(context.Result, product, (x) => x.CreatedOnUtc, utcNow); - product.UpdatedOnUtc = DateTime.UtcNow; + product.UpdatedOnUtc = utcNow; if (row.IsTransient) { @@ -540,7 +540,7 @@ public void Execute(ImportExecuteContext context) using (var scope = new DbContextScope(ctx: _rsProduct.Context, autoDetectChanges: false, proxyCreation: false, validateOnSave: false)) { var segmenter = new ImportDataSegmenter(context.DataTable); - segmenter.Culture = CultureInfo.CurrentUICulture; + var utcNow = DateTime.UtcNow; context.Result.TotalRecords = segmenter.TotalRows; @@ -558,7 +558,7 @@ public void Execute(ImportExecuteContext context) // =========================================================================== try { - ProcessProducts(context, batch); + ProcessProducts(context, batch, utcNow); } catch (Exception exception) { diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportProfileService.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportProfileService.cs index 39c0ae708e..47b9edf28c 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportProfileService.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportProfileService.cs @@ -118,7 +118,9 @@ public virtual IQueryable GetImportProfiles(bool? enabled = null) query = query.Where(x => x.Enabled == enabled.Value); } - query = query.OrderBy(x => x.Name); + query = query + .OrderBy(x => x.EntityTypeId) + .ThenBy(x => x.Name); return query; } diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs index 112646bb72..e38db2e8b3 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs @@ -67,7 +67,7 @@ private void PrepareProfileModel(ImportProfileModel model, ImportProfile profile .Select(x => Path.GetFileName(x)) .ToList(); - if (profile.FileType == ImportFileType.CSV || profile.FileType == ImportFileType.XLSX) + if (profile.FileType == ImportFileType.CSV) { var converter = new CsvConfigurationConverter(); var config = converter.ConvertFrom(profile.FileTypeConfiguration); @@ -192,7 +192,7 @@ public ActionResult Edit(ImportProfileModel model, bool continueEditing, FormCol profile.Skip = model.Skip; profile.Take = model.Take; - if (profile.FileType == ImportFileType.CSV || profile.FileType == ImportFileType.XLSX) + if (profile.FileType == ImportFileType.CSV && model.CsvConfiguration != null) { CsvConfiguration config = model.CsvConfiguration.Clone(); @@ -293,15 +293,15 @@ public JsonResult FileUpload(int id) } } } - - if (!success) - error = T("Admin.Common.UploadFileFailed"); } else { error = T("Admin.AccessDenied.Description"); } + if (!success && error.IsEmpty()) + error = T("Admin.Common.UploadFileFailed"); + if (error.HasValue()) NotifyError(error); diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Import/_CreateOrUpdate.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Import/_CreateOrUpdate.cshtml index 59d92a5c9d..c479639b6b 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Import/_CreateOrUpdate.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Import/_CreateOrUpdate.cshtml @@ -1,4 +1,5 @@ @using SmartStore.Admin.Models.DataExchange; +@using SmartStore.Core.Domain.DataExchange; @model ImportProfileModel @{ Html.AddScriptParts("~/bundles/fileupload"); @@ -119,10 +120,11 @@ }
+

+ @if (Model.CsvConfiguration != null) { var viewData = new ViewDataDictionary(); - viewData.Add("ShowGroupCaption", true); viewData.TemplateInfo.HtmlFieldPrefix = "CsvConfiguration"; viewData.ModelState.Merge(ViewData.ModelState); @Html.Partial("CsvConfiguration", Model.CsvConfiguration, viewData) From 88ef5fc4c858eaeda5f9621aa463cfb1f93c6af7 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Thu, 17 Dec 2015 18:10:36 +0100 Subject: [PATCH 096/626] Resolves #838 The initial compact db creation fails --- .../Migrations/201508042207146_RemoveKeepAlive.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Libraries/SmartStore.Data/Migrations/201508042207146_RemoveKeepAlive.cs b/src/Libraries/SmartStore.Data/Migrations/201508042207146_RemoveKeepAlive.cs index 300ceba25a..8c0dc62ad6 100644 --- a/src/Libraries/SmartStore.Data/Migrations/201508042207146_RemoveKeepAlive.cs +++ b/src/Libraries/SmartStore.Data/Migrations/201508042207146_RemoveKeepAlive.cs @@ -10,7 +10,7 @@ public partial class RemoveKeepAlive : DbMigration, ILocaleResourcesProvider, ID { public override void Up() { - if (HostingEnvironment.IsHosted) + if (HostingEnvironment.IsHosted && DataSettings.Current.IsSqlServer) { Sql("DELETE FROM [dbo].[ScheduleTask] WHERE [Type] = 'SmartStore.Services.Common.KeepAliveTask, SmartStore.Services'"); } From a9300358c3be3bf70bb7de65cc884bacf04222d4 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Thu, 17 Dec 2015 19:59:43 +0100 Subject: [PATCH 097/626] Removed some obsolete import code --- .../Domain/DataExchange/ImportEnums.cs | 11 +- .../DataExchange/Import/IImportManager.cs | 31 - .../DataExchange/Import/ImportManager.cs | 770 ------------------ .../DataExchange/Import/ImportModeFlags.cs | 13 - .../DataExchange/Import/ImportProgressInfo.cs | 63 -- .../DataExchange/Import/ImportRow.cs | 3 - .../Localization/ILocalizationService.cs | 10 +- .../Localization/LocalizationExtentions.cs | 8 +- .../Localization/LocalizationService.cs | 17 +- .../SmartStore.Services.csproj | 4 - .../DependencyRegistrar.cs | 9 +- .../Controllers/LanguageController.cs | 5 +- .../Controllers/ProductController.cs | 2 - 13 files changed, 32 insertions(+), 914 deletions(-) delete mode 100644 src/Libraries/SmartStore.Services/DataExchange/Import/IImportManager.cs delete mode 100644 src/Libraries/SmartStore.Services/DataExchange/Import/ImportManager.cs delete mode 100644 src/Libraries/SmartStore.Services/DataExchange/Import/ImportModeFlags.cs delete mode 100644 src/Libraries/SmartStore.Services/DataExchange/Import/ImportProgressInfo.cs diff --git a/src/Libraries/SmartStore.Core/Domain/DataExchange/ImportEnums.cs b/src/Libraries/SmartStore.Core/Domain/DataExchange/ImportEnums.cs index eb993124dc..00c323ae6a 100644 --- a/src/Libraries/SmartStore.Core/Domain/DataExchange/ImportEnums.cs +++ b/src/Libraries/SmartStore.Core/Domain/DataExchange/ImportEnums.cs @@ -1,4 +1,6 @@ -namespace SmartStore.Core.Domain.DataExchange +using System; + +namespace SmartStore.Core.Domain.DataExchange { /// /// Supported entity types @@ -15,4 +17,11 @@ public enum ImportFileType CSV = 0, XLSX } + + [Flags] + public enum ImportModeFlags + { + Insert = 1, + Update = 2 + } } diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/IImportManager.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/IImportManager.cs deleted file mode 100644 index 5c26d54af8..0000000000 --- a/src/Libraries/SmartStore.Services/DataExchange/Import/IImportManager.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using System.Threading; - -namespace SmartStore.Services.DataExchange.Import -{ - /// - /// Import manager interface - /// - public interface IImportManager - { - ImportResult ImportProducts( - IDataTable table, - CancellationToken cancellationToken, - IProgress progress = null); - - /// - /// Dumps an instance to a string - /// - /// The result instance - /// The report - string CreateTextReport(ImportResult result); - } - - public static class IImportManagerExtensions - { - public static ImportResult ImportProducts(this IImportManager manager, IDataTable table) - { - return manager.ImportProducts(table, CancellationToken.None); - } - } -} diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportManager.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportManager.cs deleted file mode 100644 index 6e3632eea9..0000000000 --- a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportManager.cs +++ /dev/null @@ -1,770 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using SmartStore.Core.Data; -using SmartStore.Core.Domain.Catalog; -using SmartStore.Data; -using SmartStore.Services.Catalog; -using SmartStore.Core.Events; -using SmartStore.Services.Localization; -using SmartStore.Services.Media; -using SmartStore.Services.Seo; -using SmartStore.Utilities; -using System.Text; -using SmartStore.Core.Domain.Seo; -using SmartStore.Core.Domain.Media; -using SmartStore.Services.Stores; -using SmartStore.Core.Domain.Stores; -using SmartStore.Core; -using System.Globalization; - -namespace SmartStore.Services.DataExchange.Import -{ - /// - /// Import manager - /// - public partial class ImportManager : IImportManager - { - private readonly IProductService _productService; - private readonly ICategoryService _categoryService; - private readonly IManufacturerService _manufacturerService; - private readonly IPictureService _pictureService; - private readonly IUrlRecordService _urlRecordService; - private readonly SeoSettings _seoSettings; - private readonly IEventPublisher _eventPublisher; - private readonly IRepository _rsProduct; - private readonly IRepository _rsProductCategory; - private readonly IRepository _rsProductManufacturer; - private readonly IRepository _rsPicture; - private readonly IRepository _rsProductPicture; - private readonly IRepository _rsUrlRecord; - private readonly ILanguageService _languageService; - private readonly ILocalizedEntityService _localizedEntityService; - private readonly IStoreMappingService _storeMappingService; - - public ImportManager( - IProductService productService, - ICategoryService categoryService, - IManufacturerService manufacturerService, - IPictureService pictureService, - IUrlRecordService urlRecordService, - SeoSettings seoSettings, - IEventPublisher eventPublisher, - IRepository rsProduct, - IRepository rsProductCategory, - IRepository rsProductManufacturer, - IRepository rsPicture, - IRepository rsProductPicture, - IRepository rsUrlRecord, - ILanguageService languageService, - ILocalizedEntityService localizedEntityService, - IStoreMappingService storeMappingService) - { - this._productService = productService; - this._categoryService = categoryService; - this._manufacturerService = manufacturerService; - this._pictureService = pictureService; - this._urlRecordService = urlRecordService; - this._seoSettings = seoSettings; - this._eventPublisher = eventPublisher; - this._rsProduct = rsProduct; - this._rsProductCategory = rsProductCategory; - this._rsProductManufacturer = rsProductManufacturer; - this._rsProductPicture = rsProductPicture; - this._rsUrlRecord = rsUrlRecord; - this._rsPicture = rsPicture; - this._languageService = languageService; - this._localizedEntityService = localizedEntityService; - this._storeMappingService = storeMappingService; - } - - public virtual string CreateTextReport(ImportResult result) - { - var sb = new StringBuilder(); - - using (var writer = new StringWriter(sb)) - { - writer.WriteLine("SUMMARY"); - writer.WriteLine("=================================================================================="); - writer.WriteLine("Started: {0}".FormatCurrent(result.StartDateUtc.ToLocalTime())); - writer.WriteLine("Finished: {0}{1}".FormatCurrent(result.EndDateUtc.ToLocalTime(), result.Cancelled ? " (cancelled by user)" : "")); - writer.WriteLine("Duration: {0}".FormatCurrent((result.EndDateUtc - result.StartDateUtc).ToString("g"))); - - writer.WriteLine(""); - writer.WriteLine("Total rows in source: {0}".FormatCurrent(result.TotalRecords)); - writer.WriteLine("Rows processed: {0}".FormatCurrent(result.AffectedRecords)); - writer.WriteLine("Products imported: {0}".FormatCurrent(result.NewRecords)); - writer.WriteLine("Products updated: {0}".FormatCurrent(result.ModifiedRecords)); - - writer.WriteLine(""); - writer.WriteLine("Warnings: {0}".FormatCurrent(result.Messages.Count(x => x.MessageType == ImportMessageType.Warning))); - writer.WriteLine("Errors: {0}".FormatCurrent(result.Messages.Count(x => x.MessageType == ImportMessageType.Error))); - - writer.WriteLine(""); - writer.WriteLine(""); - writer.WriteLine("MESSAGES"); - writer.WriteLine("=================================================================================="); - - foreach (var message in result.Messages) - { - string msg = string.Empty; - var prefix = new List(); - if (message.AffectedItem != null) - { - prefix.Add("Pos: " + message.AffectedItem.Position + 1); - } - if (message.AffectedField.HasValue()) - { - prefix.Add("Field: " + message.AffectedField); - } - - if (prefix.Any()) - { - msg = "[{0}] ".FormatCurrent(String.Join(", ", prefix)); - } - - msg += message.Message; - - writer.WriteLine("{0}: {1}".FormatCurrent(message.MessageType.ToString().ToUpper(), msg)); - } - } - - return sb.ToString(); - } - - /// - /// Import products from XLSX file - /// - /// Stream - public virtual ImportResult ImportProducts( - IDataTable table, - CancellationToken cancellationToken, - IProgress progress = null) - { - Guard.ArgumentNotNull(() => table); - - var result = new ImportResult(); - int saved = 0; - - if (progress != null) - progress.Report(new ImportProgressInfo { ElapsedTime = TimeSpan.Zero }); - - using (var scope = new DbContextScope(ctx: _rsProduct.Context, autoDetectChanges: false, proxyCreation: false, validateOnSave: false)) - { - try { - var segmenter = new ImportDataSegmenter(table); - - segmenter.Culture = CultureInfo.CurrentUICulture; - - result.TotalRecords = segmenter.TotalRows; - - while (segmenter.ReadNextBatch() && !cancellationToken.IsCancellationRequested) - { - var batch = segmenter.CurrentBatch; - - // Perf: detach all entities - _rsProduct.Context.DetachAll(false); - - // Update progress for calling thread - if (progress != null) - { - progress.Report(new ImportProgressInfo - { - TotalRecords = result.TotalRecords, - TotalProcessed = segmenter.CurrentSegmentFirstRowIndex - 1, - NewRecords = result.NewRecords, - ModifiedRecords = result.ModifiedRecords, - ElapsedTime = DateTime.UtcNow - result.StartDateUtc, - TotalWarnings = result.Messages.Count(x => x.MessageType == ImportMessageType.Warning), - TotalErrors = result.Messages.Count(x => x.MessageType == ImportMessageType.Error), - }); - } - - // =========================================================================== - // 1.) Import products - // =========================================================================== - try - { - saved = ProcessProducts(batch, result); - } - catch (Exception ex) - { - result.AddError(ex, segmenter.CurrentSegment, "ProcessProducts"); - } - - // reduce batch to saved (valid) products. - // No need to perform import operations on errored products. - batch = batch.Where(x => x.Entity != null && !x.IsTransient).ToArray(); - - // update result object - result.NewRecords += batch.Count(x => x.IsNew && !x.IsTransient); - result.ModifiedRecords += batch.Count(x => !x.IsNew && !x.IsTransient); - - // =========================================================================== - // 2.) Import SEO Slugs - // IMPORTANT: Unlike with Products AutoCommitEnabled must be TRUE, - // as Slugs are going to be validated against existing ones in DB. - // =========================================================================== - if (table.HasColumn("SeName") || batch.Any(x => x.IsNew || x.NameChanged)) - { - try - { - _rsProduct.Context.AutoDetectChangesEnabled = true; - ProcessSlugs(batch, result); - } - catch (Exception ex) - { - result.AddError(ex, segmenter.CurrentSegment, "ProcessSeoSlugs"); - } - finally - { - _rsProduct.Context.AutoDetectChangesEnabled = false; - } - } - - // =========================================================================== - // 3.) Import Localizations - // =========================================================================== - try - { - ProcessLocalizations(batch, result); - } - catch (Exception ex) - { - result.AddError(ex, segmenter.CurrentSegment, "ProcessLocalizations"); - } - - // =========================================================================== - // 4.) Import product category mappings - // =========================================================================== - if (table.HasColumn("CategoryIds")) - { - try - { - ProcessProductCategories(batch, result); - } - catch (Exception ex) - { - result.AddError(ex, segmenter.CurrentSegment, "ProcessProductCategories"); - } - } - - // =========================================================================== - // 5.) Import product manufacturer mappings - // =========================================================================== - if (table.HasColumn("ManufacturerIds")) - { - try - { - ProcessProductManufacturers(batch, result); - } - catch (Exception ex) - { - result.AddError(ex, segmenter.CurrentSegment, "ProcessProductManufacturers"); - } - } - - - // =========================================================================== - // 6.) Import product picture mappings - // =========================================================================== - if (table.HasColumn("Picture1") || table.HasColumn("Picture2") || table.HasColumn("Picture3")) - { - try - { - ProcessProductPictures(batch, result); - } - catch (Exception ex) - { - result.AddError(ex, segmenter.CurrentSegment, "ProcessProductPictures"); - } - } - - } - } - catch (Exception ex) - { - result.AddError(ex, null, "ReadFile"); - } - } - - result.EndDateUtc = DateTime.UtcNow; - - if (cancellationToken.IsCancellationRequested) - { - result.Cancelled = true; - result.AddInfo("Import task was cancelled by user"); - } - - return result; - } - - private int ProcessProducts(ImportRow[] batch, ImportResult result) - { - _rsProduct.AutoCommitEnabled = true; - - Product lastInserted = null; - Product lastUpdated = null; - - foreach (var row in batch) - { - Product product = null; - - object key; - var dataRow = row.DataRow; - - // try get by int ID - if (dataRow.TryGetValue("Id", out key) && key.ToString().ToInt() > 0) - { - product = _productService.GetProductById(key.ToString().ToInt()); - } - - // try get by SKU - if (product == null && dataRow.TryGetValue("SKU", out key)) - { - product = _productService.GetProductBySku(key.ToString()); - } - - // try get by GTIN - if (product == null && dataRow.TryGetValue("Gtin", out key)) - { - product = _productService.GetProductByGtin(key.ToString()); - } - - if (product == null) - { - // a Name is required with new products. - if (!row.Segmenter.HasDataColumn("Name")) - { - result.AddError("The 'Name' field is required for new products. Skipping row.", row.GetRowInfo(), "Name"); - continue; - } - product = new Product(); - } - - string name = row.GetDataValue("Name"); - - row.Initialize(product, name); - - if (!row.IsNew) - { - if (!product.Name.Equals(name, StringComparison.OrdinalIgnoreCase)) - { - // Perf: use this later for SeName updates. - row.NameChanged = true; - } - } - - row.SetProperty(result, product, (x) => x.Sku); - row.SetProperty(result, product, (x) => x.Gtin); - row.SetProperty(result, product, (x) => x.ManufacturerPartNumber); - row.SetProperty(result, product, (x) => x.ProductTypeId, (int)ProductType.SimpleProduct); - row.SetProperty(result, product, (x) => x.ParentGroupedProductId); - row.SetProperty(result, product, (x) => x.VisibleIndividually, true); - row.SetProperty(result, product, (x) => x.Name); - row.SetProperty(result, product, (x) => x.ShortDescription); - row.SetProperty(result, product, (x) => x.FullDescription); - row.SetProperty(result, product, (x) => x.ProductTemplateId); - row.SetProperty(result, product, (x) => x.ShowOnHomePage); - row.SetProperty(result, product, (x) => x.HomePageDisplayOrder); - row.SetProperty(result, product, (x) => x.MetaKeywords); - row.SetProperty(result, product, (x) => x.MetaDescription); - row.SetProperty(result, product, (x) => x.MetaTitle); - row.SetProperty(result, product, (x) => x.AllowCustomerReviews, true); - row.SetProperty(result, product, (x) => x.Published, true); - row.SetProperty(result, product, (x) => x.IsGiftCard); - row.SetProperty(result, product, (x) => x.GiftCardTypeId); - row.SetProperty(result, product, (x) => x.RequireOtherProducts); - row.SetProperty(result, product, (x) => x.RequiredProductIds); - row.SetProperty(result, product, (x) => x.AutomaticallyAddRequiredProducts); - row.SetProperty(result, product, (x) => x.IsDownload); - row.SetProperty(result, product, (x) => x.DownloadId); - row.SetProperty(result, product, (x) => x.UnlimitedDownloads, true); - row.SetProperty(result, product, (x) => x.MaxNumberOfDownloads, 10); - row.SetProperty(result, product, (x) => x.DownloadActivationTypeId, 1); - row.SetProperty(result, product, (x) => x.HasSampleDownload); - row.SetProperty(result, product, (x) => x.SampleDownloadId, (int?)null, ZeroToNull); - row.SetProperty(result, product, (x) => x.HasUserAgreement); - row.SetProperty(result, product, (x) => x.UserAgreementText); - row.SetProperty(result, product, (x) => x.IsRecurring); - row.SetProperty(result, product, (x) => x.RecurringCycleLength, 100); - row.SetProperty(result, product, (x) => x.RecurringCyclePeriodId); - row.SetProperty(result, product, (x) => x.RecurringTotalCycles, 10); - row.SetProperty(result, product, (x) => x.IsShipEnabled, true); - row.SetProperty(result, product, (x) => x.IsFreeShipping); - row.SetProperty(result, product, (x) => x.AdditionalShippingCharge); - row.SetProperty(result, product, (x) => x.IsEsd); - row.SetProperty(result, product, (x) => x.IsTaxExempt); - row.SetProperty(result, product, (x) => x.TaxCategoryId, 1); - row.SetProperty(result, product, (x) => x.ManageInventoryMethodId); - row.SetProperty(result, product, (x) => x.StockQuantity, 10000); - row.SetProperty(result, product, (x) => x.DisplayStockAvailability); - row.SetProperty(result, product, (x) => x.DisplayStockQuantity); - row.SetProperty(result, product, (x) => x.MinStockQuantity); - row.SetProperty(result, product, (x) => x.LowStockActivityId); - row.SetProperty(result, product, (x) => x.NotifyAdminForQuantityBelow, 1); - row.SetProperty(result, product, (x) => x.BackorderModeId); - row.SetProperty(result, product, (x) => x.AllowBackInStockSubscriptions); - row.SetProperty(result, product, (x) => x.OrderMinimumQuantity, 1); - row.SetProperty(result, product, (x) => x.OrderMaximumQuantity, 10000); - row.SetProperty(result, product, (x) => x.AllowedQuantities); - row.SetProperty(result, product, (x) => x.DisableBuyButton); - row.SetProperty(result, product, (x) => x.DisableWishlistButton); - row.SetProperty(result, product, (x) => x.AvailableForPreOrder); - row.SetProperty(result, product, (x) => x.CallForPrice); - row.SetProperty(result, product, (x) => x.Price); - row.SetProperty(result, product, (x) => x.OldPrice); - row.SetProperty(result, product, (x) => x.ProductCost); - row.SetProperty(result, product, (x) => x.SpecialPrice); - row.SetProperty(result, product, (x) => x.SpecialPriceStartDateTimeUtc); - row.SetProperty(result, product, (x) => x.SpecialPriceEndDateTimeUtc); - row.SetProperty(result, product, (x) => x.CustomerEntersPrice); - row.SetProperty(result, product, (x) => x.MinimumCustomerEnteredPrice); - row.SetProperty(result, product, (x) => x.MaximumCustomerEnteredPrice, 1000); - row.SetProperty(result, product, (x) => x.Weight); - row.SetProperty(result, product, (x) => x.Length); - row.SetProperty(result, product, (x) => x.Width); - row.SetProperty(result, product, (x) => x.Height); - row.SetProperty(result, product, (x) => x.DeliveryTimeId); - row.SetProperty(result, product, (x) => x.QuantityUnitId); - row.SetProperty(result, product, (x) => x.BasePriceEnabled); - row.SetProperty(result, product, (x) => x.BasePriceMeasureUnit); - row.SetProperty(result, product, (x) => x.BasePriceAmount); - row.SetProperty(result, product, (x) => x.BasePriceBaseAmount); - row.SetProperty(result, product, (x) => x.BundlePerItemPricing); - row.SetProperty(result, product, (x) => x.BundlePerItemShipping); - row.SetProperty(result, product, (x) => x.BundlePerItemShoppingCart); - row.SetProperty(result, product, (x) => x.BundleTitleText); - row.SetProperty(result, product, (x) => x.AvailableStartDateTimeUtc); - row.SetProperty(result, product, (x) => x.AvailableEndDateTimeUtc); - row.SetProperty(result, product, (x) => x.LimitedToStores); - - var storeIds = row.GetDataValue>("StoreIds"); - if (storeIds != null && storeIds.Any()) - { - _storeMappingService.SaveStoreMappings(product, storeIds.ToArray()); - } - - row.SetProperty(result, product, (x) => x.CreatedOnUtc, DateTime.UtcNow); - - product.UpdatedOnUtc = DateTime.UtcNow; - - if (row.IsTransient) - { - _rsProduct.Insert(product); - lastInserted = product; - } - else - { - _rsProduct.Update(product); - lastUpdated = product; - } - } - - // commit whole batch at once - var num = _rsProduct.Context.SaveChanges(); - - // Perf: notify only about LAST insertion and update - if (lastInserted != null) - _eventPublisher.EntityInserted(lastInserted); - if (lastUpdated != null) - _eventPublisher.EntityUpdated(lastUpdated); - - return num; - } - - private int ProcessSlugs(ImportRow[] batch, ImportResult result) - { - var slugMap = new Dictionary(100); - Func slugLookup = ((s) => { - if (slugMap.ContainsKey(s)) - { - return slugMap[s]; - } - return (UrlRecord)null; - }); - - var entityName = typeof(Product).Name; - - foreach (var row in batch) - { - if (row.IsNew || row.NameChanged || row.Segmenter.HasDataColumn("SeName")) - { - try - { - string seName = row.GetDataValue("SeName"); - seName = row.Entity.ValidateSeName(seName, row.Entity.Name, true, _urlRecordService, _seoSettings, extraSlugLookup: slugLookup); - - UrlRecord urlRecord = null; - - if (row.IsNew) - { - // dont't bother validating SeName for new entities. - urlRecord = new UrlRecord - { - EntityId = row.Entity.Id, - EntityName = entityName, - Slug = seName, - LanguageId = 0, - IsActive = true, - }; - _rsUrlRecord.Insert(urlRecord); - } - else - { - urlRecord = _urlRecordService.SaveSlug(row.Entity, seName, 0); - } - - if (urlRecord != null) - { - // a new record was inserted to the store: keep track of it for this batch. - slugMap[seName] = urlRecord; - } - } - catch (Exception ex) - { - result.AddWarning(ex.Message, row.GetRowInfo(), "SeName"); - } - } - } - - // commit whole batch at once - return _rsUrlRecord.Context.SaveChanges(); - } - - private int ProcessLocalizations(ImportRow[] batch, ImportResult result) - { - //_rsProductManufacturer.AutoCommitEnabled = false; - - //string lastInserted = null; - - var languages = _languageService.GetAllLanguages(true); - - foreach (var row in batch) - { - - Product product = null; - - //get product - try - { - product = _productService.GetProductById(row.Entity.Id); - } - catch (Exception ex) - { - result.AddWarning(ex.Message, row.GetRowInfo(), "ProcessLocalizations Product"); - } - - foreach (var lang in languages) - { - string localizedName = row.GetDataValue("Name", lang.UniqueSeoCode); - string localizedShortDescription = row.GetDataValue("ShortDescription", lang.UniqueSeoCode); - string localizedFullDescription = row.GetDataValue("FullDescription", lang.UniqueSeoCode); - - if (localizedName.HasValue()) - { - _localizedEntityService.SaveLocalizedValue(product, x => x.Name, localizedName, lang.Id); - } - if (localizedShortDescription.HasValue()) - { - _localizedEntityService.SaveLocalizedValue(product, x => x.ShortDescription, localizedShortDescription, lang.Id); - } - if (localizedFullDescription.HasValue()) - { - _localizedEntityService.SaveLocalizedValue(product, x => x.FullDescription, localizedFullDescription, lang.Id); - } - } - } - - // commit whole batch at once - var num = _rsProductManufacturer.Context.SaveChanges(); - - // Perf: notify only about LAST insertion and update - //if (lastInserted != null) - // _eventPublisher.EntityInserted(lastInserted); - - return num; - } - - private int ProcessProductCategories(ImportRow[] batch, ImportResult result) - { - _rsProductCategory.AutoCommitEnabled = false; - - ProductCategory lastInserted = null; - - foreach (var row in batch) - { - var categoryIds = row.GetDataValue>("CategoryIds"); - if (categoryIds != null && categoryIds.Any()) - { - try - { - foreach (var id in categoryIds) - { - if (_rsProductCategory.TableUntracked.Where(x => x.ProductId == row.Entity.Id && x.CategoryId == id).FirstOrDefault() == null) - { - // ensure that category exists - var category = _categoryService.GetCategoryById(id); - if (category != null) - { - var productCategory = new ProductCategory - { - ProductId = row.Entity.Id, - CategoryId = category.Id, - IsFeaturedProduct = false, - DisplayOrder = 1 - }; - _rsProductCategory.Insert(productCategory); - lastInserted = productCategory; - } - } - } - } - catch (Exception ex) - { - result.AddWarning(ex.Message, row.GetRowInfo(), "CategoryIds"); - } - } - } - - // commit whole batch at once - var num = _rsProductCategory.Context.SaveChanges(); - - // Perf: notify only about LAST insertion and update - if (lastInserted != null) - _eventPublisher.EntityInserted(lastInserted); - - return num; - } - - private int ProcessProductManufacturers(ImportRow[] batch, ImportResult result) - { - _rsProductManufacturer.AutoCommitEnabled = false; - - ProductManufacturer lastInserted = null; - - foreach (var row in batch) - { - var manufacturerIds = row.GetDataValue>("ManufacturerIds"); - if (manufacturerIds != null && manufacturerIds.Any()) - { - try - { - foreach (var id in manufacturerIds) - { - if (_rsProductManufacturer.TableUntracked.Where(x => x.ProductId == row.Entity.Id && x.ManufacturerId == id).FirstOrDefault() == null) - { - // ensure that manufacturer exists - var manufacturer = _manufacturerService.GetManufacturerById(id); - if (manufacturer != null) - { - var productManufacturer = new ProductManufacturer - { - ProductId = row.Entity.Id, - ManufacturerId = manufacturer.Id, - IsFeaturedProduct = false, - DisplayOrder = 1 - }; - _rsProductManufacturer.Insert(productManufacturer); - lastInserted = productManufacturer; - } - } - } - } - catch (Exception ex) - { - result.AddWarning(ex.Message, row.GetRowInfo(), "ManufacturerIds"); - } - } - } - - // commit whole batch at once - var num = _rsProductManufacturer.Context.SaveChanges(); - - // Perf: notify only about LAST insertion and update - if (lastInserted != null) - _eventPublisher.EntityInserted(lastInserted); - - return num; - } - - private void ProcessProductPictures(ImportRow[] batch, ImportResult result) - { - // true, cause pictures must be saved and assigned an id - // prior adding a mapping. - _rsProductPicture.AutoCommitEnabled = true; - - ProductPicture lastInserted = null; - int equalPictureId = 0; - - foreach (var row in batch) - { - var pictures = new string[] - { - row.GetDataValue("Picture1"), - row.GetDataValue("Picture2"), - row.GetDataValue("Picture3") - }; - - int i = 0; - try - { - for (i = 0; i < pictures.Length; i++) - { - var picture = pictures[i]; - - if (picture.IsEmpty() || !File.Exists(picture)) - continue; - - var currentPictures = _rsProductPicture.TableUntracked.Expand(x => x.Picture).Where(x => x.ProductId == row.Entity.Id).Select(x => x.Picture).ToList(); - var pictureBinary = _pictureService.FindEqualPicture(picture, currentPictures, out equalPictureId); - - if (pictureBinary != null && pictureBinary.Length > 0) - { - // no equal picture found in sequence - var newPicture = _pictureService.InsertPicture(pictureBinary, "image/jpeg", _pictureService.GetPictureSeName(row.EntityDisplayName), true, false, false); - if (newPicture != null) - { - var mapping = new ProductPicture - { - ProductId = row.Entity.Id, - PictureId = newPicture.Id, - DisplayOrder = 1, - }; - _rsProductPicture.Insert(mapping); - lastInserted = mapping; - } - } - else - { - result.AddInfo("Found equal picture in data store. Skipping field.", row.GetRowInfo(), "Picture" + (i + 1).ToString()); - } - } - } - catch (Exception ex) - { - result.AddWarning(ex.Message, row.GetRowInfo(), "Picture" + (i + 1).ToString()); - } - - } - - // Perf: notify only about LAST insertion and update - if (lastInserted != null) - _eventPublisher.EntityInserted(lastInserted); - } - - private int? ZeroToNull(object value, CultureInfo culture) - { - int result; - if (CommonHelper.TryConvert(value, culture, out result) && result > 0) - { - return result; - } - - return (int?)null; - } - } -} diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportModeFlags.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportModeFlags.cs deleted file mode 100644 index 1e85010067..0000000000 --- a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportModeFlags.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; - -namespace SmartStore.Services.DataExchange.Import -{ - - [Flags] - public enum ImportModeFlags - { - Insert = 1, - Update = 2 - } - -} diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportProgressInfo.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportProgressInfo.cs deleted file mode 100644 index 19419845d0..0000000000 --- a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportProgressInfo.cs +++ /dev/null @@ -1,63 +0,0 @@ -using System; - -namespace SmartStore.Services.DataExchange.Import -{ - - public class ImportProgressInfo - { - - public int TotalRecords - { - get; - set; - } - - public int TotalProcessed - { - get; - set; - } - - public double ProcessedPercent - { - get - { - if (TotalRecords == 0) - return 0; - - return ((double)TotalProcessed / (double)TotalRecords) * 100; - } - } - - public int NewRecords - { - get; - set; - } - - public int ModifiedRecords - { - get; - set; - } - - public TimeSpan ElapsedTime - { - get; - set; - } - - public int TotalWarnings - { - get; - set; - } - - public int TotalErrors - { - get; - set; - } - } - -} diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportRow.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportRow.cs index 9ca5ab441b..5b469a9352 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportRow.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportRow.cs @@ -1,9 +1,6 @@ using System; -using System.Collections.Generic; using System.Globalization; -using System.Linq; using System.Linq.Expressions; -using System.Text; using SmartStore.ComponentModel; using SmartStore.Core; diff --git a/src/Libraries/SmartStore.Services/Localization/ILocalizationService.cs b/src/Libraries/SmartStore.Services/Localization/ILocalizationService.cs index 9f1cc99290..918ad1be88 100644 --- a/src/Libraries/SmartStore.Services/Localization/ILocalizationService.cs +++ b/src/Libraries/SmartStore.Services/Localization/ILocalizationService.cs @@ -1,16 +1,16 @@ using System; using System.Collections.Generic; using System.Xml; +using SmartStore.Core.Domain.DataExchange; using SmartStore.Core.Domain.Localization; using SmartStore.Core.Plugins; -using SmartStore.Services.DataExchange.Import; namespace SmartStore.Services.Localization { - /// - /// Localization manager interface - /// - public partial interface ILocalizationService + /// + /// Localization manager interface + /// + public partial interface ILocalizationService { void ClearCache(); diff --git a/src/Libraries/SmartStore.Services/Localization/LocalizationExtentions.cs b/src/Libraries/SmartStore.Services/Localization/LocalizationExtentions.cs index 8bbd78cf9b..a55b8ab84f 100644 --- a/src/Libraries/SmartStore.Services/Localization/LocalizationExtentions.cs +++ b/src/Libraries/SmartStore.Services/Localization/LocalizationExtentions.cs @@ -1,18 +1,18 @@ using System; using System.Linq.Expressions; using System.Reflection; +using System.Xml; +using SmartStore.ComponentModel; using SmartStore.Core; +using SmartStore.Core.Domain.DataExchange; using SmartStore.Core.Domain.Localization; using SmartStore.Core.Infrastructure; using SmartStore.Core.Plugins; -using System.Xml; using SmartStore.Utilities; -using SmartStore.Services.DataExchange.Import; -using SmartStore.ComponentModel; namespace SmartStore.Services.Localization { - public static class LocalizationExtentions + public static class LocalizationExtentions { /// /// Get localized property of an entity diff --git a/src/Libraries/SmartStore.Services/Localization/LocalizationService.cs b/src/Libraries/SmartStore.Services/Localization/LocalizationService.cs index 21cf03447f..31f83eb7dc 100644 --- a/src/Libraries/SmartStore.Services/Localization/LocalizationService.cs +++ b/src/Libraries/SmartStore.Services/Localization/LocalizationService.cs @@ -1,29 +1,28 @@ using System; +using System.Collections; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Data; using System.IO; using System.Linq; using System.Text; +using System.Text.RegularExpressions; using System.Xml; using SmartStore.Core; using SmartStore.Core.Caching; using SmartStore.Core.Data; +using SmartStore.Core.Domain.DataExchange; using SmartStore.Core.Domain.Localization; using SmartStore.Core.Events; using SmartStore.Core.Logging; using SmartStore.Core.Plugins; -using System.Text.RegularExpressions; -using System.Collections.Concurrent; -using System.Web.Mvc; -using System.Collections; -using SmartStore.Services.DataExchange.Import; namespace SmartStore.Services.Localization { - /// - /// Provides information about localization - /// - public partial class LocalizationService : ILocalizationService + /// + /// Provides information about localization + /// + public partial class LocalizationService : ILocalizationService { #region Constants private const string LOCALESTRINGRESOURCES_ALL_KEY = "SmartStore.lsr.all-{0}"; diff --git a/src/Libraries/SmartStore.Services/SmartStore.Services.csproj b/src/Libraries/SmartStore.Services/SmartStore.Services.csproj index 8af64def3c..b82c8f43a1 100644 --- a/src/Libraries/SmartStore.Services/SmartStore.Services.csproj +++ b/src/Libraries/SmartStore.Services/SmartStore.Services.csproj @@ -198,8 +198,6 @@ - - @@ -361,7 +359,6 @@ - @@ -380,7 +377,6 @@ - diff --git a/src/Presentation/SmartStore.Web.Framework/DependencyRegistrar.cs b/src/Presentation/SmartStore.Web.Framework/DependencyRegistrar.cs index 8c49b043ed..37ea64ef94 100644 --- a/src/Presentation/SmartStore.Web.Framework/DependencyRegistrar.cs +++ b/src/Presentation/SmartStore.Web.Framework/DependencyRegistrar.cs @@ -67,17 +67,16 @@ using SmartStore.Services.Themes; using SmartStore.Services.Topics; using SmartStore.Utilities; -using SmartStore.Web.Framework.Controllers; +using SmartStore.Web.Framework.Bundling; +using SmartStore.Web.Framework.Filters; using SmartStore.Web.Framework.Localization; using SmartStore.Web.Framework.Plugins; +using SmartStore.Web.Framework.Routing; using SmartStore.Web.Framework.Theming; using SmartStore.Web.Framework.UI; using SmartStore.Web.Framework.WebApi; using SmartStore.Web.Framework.WebApi.Configuration; using Module = Autofac.Module; -using SmartStore.Web.Framework.Bundling; -using SmartStore.Web.Framework.Filters; -using SmartStore.Web.Framework.Routing; namespace SmartStore.Web.Framework { @@ -241,8 +240,6 @@ protected override void Load(ContainerBuilder builder) builder.RegisterType().As().InstancePerRequest(); builder.RegisterType().As().InstancePerRequest(); - - builder.RegisterType().As().InstancePerRequest(); builder.RegisterType().As().InstancePerRequest(); builder.RegisterType().As().InstancePerRequest(); diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/LanguageController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/LanguageController.cs index 0d7cbbd0dd..e546998d03 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/LanguageController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/LanguageController.cs @@ -2,15 +2,14 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Text; using System.Web.Mvc; using SmartStore.Admin.Models.Localization; using SmartStore.Core; using SmartStore.Core.Data; using SmartStore.Core.Domain.Common; +using SmartStore.Core.Domain.DataExchange; using SmartStore.Core.Domain.Localization; using SmartStore.Core.Plugins; -using SmartStore.Services.DataExchange.Import; using SmartStore.Services.Localization; using SmartStore.Services.Security; using SmartStore.Services.Stores; @@ -23,7 +22,7 @@ namespace SmartStore.Admin.Controllers { - [AdminAuthorize] + [AdminAuthorize] public partial class LanguageController : AdminControllerBase { #region Fields diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/ProductController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/ProductController.cs index 8270ea5cdb..e1f0748bfc 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/ProductController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/ProductController.cs @@ -23,7 +23,6 @@ using SmartStore.Services.Catalog; using SmartStore.Services.Common; using SmartStore.Services.Customers; -using SmartStore.Services.DataExchange.Import; using SmartStore.Services.Directory; using SmartStore.Services.Discounts; using SmartStore.Services.Helpers; @@ -110,7 +109,6 @@ public ProductController( ITaxCategoryService taxCategoryService, IProductTagService productTagService, ICopyProductService copyProductService, - IImportManager importManager, ICustomerActivityService customerActivityService, IPermissionService permissionService, IAclService aclService, From 8f0e4b30e17b9537fd2a018ec10ec089510b3147 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Fri, 18 Dec 2015 14:33:42 +0100 Subject: [PATCH 098/626] Added category importer --- changelog.md | 1 + .../Domain/DataExchange/ImportEnums.cs | 3 +- .../201512151526290_ImportFramework.cs | 3 +- .../Catalog/Importer/CategoryImporter.cs | 282 ++++++++++++++++++ .../Catalog/Importer/ProductImporter.cs | 13 +- .../Customers/Importer/CustomerImporter.cs | 15 +- .../DataExchange/Import/DataImporter.cs | 5 +- .../SmartStore.Services.csproj | 1 + 8 files changed, 308 insertions(+), 15 deletions(-) create mode 100644 src/Libraries/SmartStore.Services/Catalog/Importer/CategoryImporter.cs diff --git a/changelog.md b/changelog.md index 1c11d670f2..6294b6d91e 100644 --- a/changelog.md +++ b/changelog.md @@ -29,6 +29,7 @@ * Admin > System > System Info shows used application memory (RAM) * Added option to make VATIN mandatory during customer registration * Customer import +* Category import ### Improvements * (Perf) Implemented static caches for URL aliases and localized properties. Increases app startup and request speed by up to 30%. diff --git a/src/Libraries/SmartStore.Core/Domain/DataExchange/ImportEnums.cs b/src/Libraries/SmartStore.Core/Domain/DataExchange/ImportEnums.cs index 00c323ae6a..d3ea351a16 100644 --- a/src/Libraries/SmartStore.Core/Domain/DataExchange/ImportEnums.cs +++ b/src/Libraries/SmartStore.Core/Domain/DataExchange/ImportEnums.cs @@ -9,7 +9,8 @@ public enum ImportEntityType { Product = 0, Customer, - NewsLetterSubscription + NewsLetterSubscription, + Category } public enum ImportFileType diff --git a/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs b/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs index 2bc57f326a..3d1227f9c4 100644 --- a/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs +++ b/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs @@ -102,7 +102,8 @@ public void MigrateLocaleResources(LocaleResourcesBuilder builder) builder.AddOrUpdate("Enums.SmartStore.Core.Domain.DataExchange.ImportEntityType.Product", "Product", "Produkt"); builder.AddOrUpdate("Enums.SmartStore.Core.Domain.DataExchange.ImportEntityType.Customer", "Customer", "Kunde"); - builder.AddOrUpdate("Enums.SmartStore.Core.Domain.DataExchange.ImportEntityType.NewsLetterSubscription", "Newsletter Subscribers", "Newsletter Abonnenten"); + builder.AddOrUpdate("Enums.SmartStore.Core.Domain.DataExchange.ImportEntityType.NewsLetterSubscription", "Newsletter Subscriber", "Newsletter Abonnent"); + builder.AddOrUpdate("Enums.SmartStore.Core.Domain.DataExchange.ImportEntityType.Category", "Category", "Warengruppe"); builder.AddOrUpdate("Enums.SmartStore.Core.Domain.DataExchange.ImportFileType.CSV", "Delimiter separated values (.csv)", "Trennzeichen getrennte Werte (.csv)"); builder.AddOrUpdate("Enums.SmartStore.Core.Domain.DataExchange.ImportFileType.XLSX", "Excel (.xlsx)", "Excel (.xlsx)"); diff --git a/src/Libraries/SmartStore.Services/Catalog/Importer/CategoryImporter.cs b/src/Libraries/SmartStore.Services/Catalog/Importer/CategoryImporter.cs new file mode 100644 index 0000000000..2805097bc6 --- /dev/null +++ b/src/Libraries/SmartStore.Services/Catalog/Importer/CategoryImporter.cs @@ -0,0 +1,282 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using SmartStore.Core.Data; +using SmartStore.Core.Domain.Catalog; +using SmartStore.Core.Domain.DataExchange; +using SmartStore.Core.Domain.Media; +using SmartStore.Core.Domain.Seo; +using SmartStore.Core.Events; +using SmartStore.Services.DataExchange.Import; +using SmartStore.Services.Seo; +using SmartStore.Services.Stores; + +namespace SmartStore.Services.Catalog.Importer +{ + public class CategoryImporter : IEntityImporter + { + private readonly IRepository _categoryRepository; + private readonly IRepository _urlRecordRepository; + private readonly IRepository _pictureRepository; + private readonly ICommonServices _services; + private readonly ICategoryService _categoryService; + private readonly IUrlRecordService _urlRecordService; + private readonly ICategoryTemplateService _categoryTemplateService; + private readonly IStoreMappingService _storeMappingService; + private readonly SeoSettings _seoSettings; + + public CategoryImporter( + IRepository categoryRepository, + IRepository urlRecordRepository, + IRepository pictureRepository, + ICommonServices services, + ICategoryService categoryService, + IUrlRecordService urlRecordService, + ICategoryTemplateService categoryTemplateService, + IStoreMappingService storeMappingService, + SeoSettings seoSettings) + { + _categoryRepository = categoryRepository; + _urlRecordRepository = urlRecordRepository; + _pictureRepository = pictureRepository; + _services = services; + _categoryService = categoryService; + _urlRecordService = urlRecordService; + _categoryTemplateService = categoryTemplateService; + _storeMappingService = storeMappingService; + _seoSettings = seoSettings; + } + + private int ProcessSlugs(ImportExecuteContext context, ImportRow[] batch) + { + var slugMap = new Dictionary(100); + Func slugLookup = ((s) => + { + if (slugMap.ContainsKey(s)) + { + return slugMap[s]; + } + return (UrlRecord)null; + }); + + var entityName = typeof(Category).Name; + + foreach (var row in batch) + { + if (row.IsNew || row.NameChanged || row.Segmenter.HasDataColumn("SeName")) + { + try + { + string seName = row.GetDataValue("SeName"); + seName = row.Entity.ValidateSeName(seName, row.Entity.Name, true, _urlRecordService, _seoSettings, extraSlugLookup: slugLookup); + + UrlRecord urlRecord = null; + + if (row.IsNew) + { + // dont't bother validating SeName for new entities. + urlRecord = new UrlRecord + { + EntityId = row.Entity.Id, + EntityName = entityName, + Slug = seName, + LanguageId = 0, + IsActive = true, + }; + _urlRecordRepository.Insert(urlRecord); + } + else + { + urlRecord = _urlRecordService.SaveSlug(row.Entity, seName, 0); + } + + if (urlRecord != null) + { + // a new record was inserted to the store: keep track of it for this batch. + slugMap[seName] = urlRecord; + } + } + catch (Exception exception) + { + context.Result.AddWarning(exception.Message, row.GetRowInfo(), "SeName"); + } + } + } + + // commit whole batch at once + return _urlRecordRepository.Context.SaveChanges(); + } + + private int ProcessCategories(ImportExecuteContext context, + ImportRow[] batch, + DateTime utcNow, + List allCategoryTemplateIds) + { + _categoryRepository.AutoCommitEnabled = true; + + Category lastInserted = null; + Category lastUpdated = null; + var defaultTemplateId = allCategoryTemplateIds.First(); + + foreach (var row in batch) + { + Category category = null; + object key; + + // try get by int ID + if (row.DataRow.TryGetValue("Id", out key) && key.ToString().ToInt() > 0) + { + category = _categoryService.GetCategoryById(key.ToString().ToInt()); + } + + if (category == null) + { + // a Name is required with new categories + if (!row.Segmenter.HasDataColumn("Name")) + { + context.Result.AddError("The 'Name' field is required for new categories. Skipping row.", row.GetRowInfo(), "Name"); + continue; + } + category = new Category + { + CategoryTemplateId = defaultTemplateId + }; + } + + var name = row.GetDataValue("Name"); + + row.Initialize(category, name); + + if (!row.IsNew && !category.Name.Equals(name, StringComparison.OrdinalIgnoreCase)) + { + // Perf: use this later for SeName updates. + row.NameChanged = true; + } + + row.SetProperty(context.Result, category, (x) => x.Name); + row.SetProperty(context.Result, category, (x) => x.FullName); + row.SetProperty(context.Result, category, (x) => x.Description); + row.SetProperty(context.Result, category, (x) => x.BottomDescription); + row.SetProperty(context.Result, category, (x) => x.MetaKeywords); + row.SetProperty(context.Result, category, (x) => x.MetaDescription); + row.SetProperty(context.Result, category, (x) => x.MetaTitle); + row.SetProperty(context.Result, category, (x) => x.ParentCategoryId); // TODO: hierachical data in batch processing? + row.SetProperty(context.Result, category, (x) => x.PageSize, 12); + row.SetProperty(context.Result, category, (x) => x.AllowCustomersToSelectPageSize, true); + row.SetProperty(context.Result, category, (x) => x.PageSizeOptions); + row.SetProperty(context.Result, category, (x) => x.PriceRanges); + row.SetProperty(context.Result, category, (x) => x.ShowOnHomePage); + row.SetProperty(context.Result, category, (x) => x.HasDiscountsApplied); + row.SetProperty(context.Result, category, (x) => x.Published, true); + row.SetProperty(context.Result, category, (x) => x.DisplayOrder); + row.SetProperty(context.Result, category, (x) => x.LimitedToStores); + row.SetProperty(context.Result, category, (x) => x.Alias); + row.SetProperty(context.Result, category, (x) => x.DefaultViewMode); + + if (row.DataRow.TryGetValue("CategoryTemplateId", out key)) + { + int templateId = key.ToString().ToInt(); + if (templateId > 0 && allCategoryTemplateIds.Contains(templateId)) + category.CategoryTemplateId = templateId; + } + + if (row.DataRow.TryGetValue("PictureId", out key)) + { + int pictureId = key.ToString().ToInt(); + if (pictureId > 0 && _pictureRepository.TableUntracked.Any(x => x.Id == pictureId)) + category.PictureId = pictureId; + } + + var storeIds = row.GetDataValue>("StoreIds"); + if (storeIds != null && storeIds.Any()) + { + _storeMappingService.SaveStoreMappings(category, storeIds.ToArray()); + } + + row.SetProperty(context.Result, category, (x) => x.CreatedOnUtc, utcNow); + category.UpdatedOnUtc = utcNow; + + if (row.IsTransient) + { + _categoryRepository.Insert(category); + lastInserted = category; + } + else + { + _categoryRepository.Update(category); + lastUpdated = category; + } + } + + // commit whole batch at once + var num = _categoryRepository.Context.SaveChanges(); + + // Perf: notify only about LAST insertion and update + if (lastInserted != null) + _services.EventPublisher.EntityInserted(lastInserted); + if (lastUpdated != null) + _services.EventPublisher.EntityUpdated(lastUpdated); + + return num; + } + + public void Execute(ImportExecuteContext context) + { + var allCategoryTemplateIds = _categoryTemplateService.GetAllCategoryTemplates() + .Select(x => x.Id) + .ToList(); + + using (var scope = new DbContextScope(ctx: _categoryRepository.Context, autoDetectChanges: false, proxyCreation: false, validateOnSave: false)) + { + var segmenter = new ImportDataSegmenter(context.DataTable); + var utcNow = DateTime.UtcNow; + + context.Result.TotalRecords = segmenter.TotalRows; + + while (context.Abort == DataExchangeAbortion.None && segmenter.ReadNextBatch()) + { + var batch = segmenter.CurrentBatch; + + // Perf: detach all entities + _categoryRepository.Context.DetachAll(false); + + context.SetProgress(segmenter.CurrentSegmentFirstRowIndex - 1, segmenter.TotalRows); + + try + { + ProcessCategories(context, batch, utcNow, allCategoryTemplateIds); + } + catch (Exception exception) + { + context.Result.AddError(exception, segmenter.CurrentSegment, "ProcessCategories"); + } + + // reduce batch to saved (valid) products. + // No need to perform import operations on errored products. + batch = batch.Where(x => x.Entity != null && !x.IsTransient).ToArray(); + + // update result object + context.Result.NewRecords += batch.Count(x => x.IsNew && !x.IsTransient); + context.Result.ModifiedRecords += batch.Count(x => !x.IsNew && !x.IsTransient); + + if (context.DataTable.HasColumn("SeName") || batch.Any(x => x.IsNew || x.NameChanged)) + { + try + { + _categoryRepository.Context.AutoDetectChangesEnabled = true; + ProcessSlugs(context, batch); + } + catch (Exception exception) + { + context.Result.AddError(exception, segmenter.CurrentSegment, "ProcessSlugs"); + } + finally + { + _categoryRepository.Context.AutoDetectChangesEnabled = false; + } + } + } + } + } + } +} diff --git a/src/Libraries/SmartStore.Services/Catalog/Importer/ProductImporter.cs b/src/Libraries/SmartStore.Services/Catalog/Importer/ProductImporter.cs index dd0195f223..24eaa38231 100644 --- a/src/Libraries/SmartStore.Services/Catalog/Importer/ProductImporter.cs +++ b/src/Libraries/SmartStore.Services/Catalog/Importer/ProductImporter.cs @@ -371,24 +371,22 @@ private int ProcessProducts(ImportExecuteContext context, ImportRow[] b foreach (var row in batch) { Product product = null; - object key; - var dataRow = row.DataRow; // try get by int ID - if (dataRow.TryGetValue("Id", out key) && key.ToString().ToInt() > 0) + if (row.DataRow.TryGetValue("Id", out key) && key.ToString().ToInt() > 0) { product = _productService.GetProductById(key.ToString().ToInt()); } // try get by SKU - if (product == null && dataRow.TryGetValue("SKU", out key)) + if (product == null && row.DataRow.TryGetValue("SKU", out key)) { product = _productService.GetProductBySku(key.ToString()); } // try get by GTIN - if (product == null && dataRow.TryGetValue("Gtin", out key)) + if (product == null && row.DataRow.TryGetValue("Gtin", out key)) { product = _productService.GetProductByGtin(key.ToString()); } @@ -404,7 +402,7 @@ private int ProcessProducts(ImportExecuteContext context, ImportRow[] b product = new Product(); } - string name = row.GetDataValue("Name"); + var name = row.GetDataValue("Name"); row.Initialize(product, name); @@ -508,7 +506,6 @@ private int ProcessProducts(ImportExecuteContext context, ImportRow[] b } row.SetProperty(context.Result, product, (x) => x.CreatedOnUtc, utcNow); - product.UpdatedOnUtc = utcNow; if (row.IsTransient) @@ -587,7 +584,7 @@ public void Execute(ImportExecuteContext context) } catch (Exception exception) { - context.Result.AddError(exception, segmenter.CurrentSegment, "ProcessSeoSlugs"); + context.Result.AddError(exception, segmenter.CurrentSegment, "ProcessSlugs"); } finally { diff --git a/src/Libraries/SmartStore.Services/Customers/Importer/CustomerImporter.cs b/src/Libraries/SmartStore.Services/Customers/Importer/CustomerImporter.cs index c5204fe8aa..4236fa81f8 100644 --- a/src/Libraries/SmartStore.Services/Customers/Importer/CustomerImporter.cs +++ b/src/Libraries/SmartStore.Services/Customers/Importer/CustomerImporter.cs @@ -197,7 +197,12 @@ private int ProcessCustomers(ImportExecuteContext context, if (customer == null) { - customer = new Customer(); + customer = new Customer + { + CustomerGuid = new Guid(), + AffiliateId = 0, + Active = true + }; } else { @@ -205,7 +210,6 @@ private int ProcessCustomers(ImportExecuteContext context, } var email = row.GetDataValue("Email"); - var affiliateId = row.GetDataValue("AffiliateId"); var isGuest = row.GetDataValue("IsGuest"); var isRegistered = row.GetDataValue("IsRegistered"); var isAdmin = row.GetDataValue("IsAdministrator"); @@ -231,11 +235,14 @@ private int ProcessCustomers(ImportExecuteContext context, row.SetProperty(context.Result, customer, (x) => x.CreatedOnUtc, utcNow); row.SetProperty(context.Result, customer, (x) => x.LastActivityDateUtc, utcNow); - if (affiliateId != 0 && allAffiliateIds.Contains(affiliateId)) + if (row.DataRow.TryGetValue("AffiliateId", out key)) { - row.SetProperty(context.Result, customer, (x) => x.AffiliateId, affiliateId); + int affiliateId = key.ToString().ToInt(); + if (affiliateId > 0 && allAffiliateIds.Contains(affiliateId)) + customer.AffiliateId = affiliateId; } + UpsertRole(row, guestRole, SystemCustomerRoleNames.Guests, isGuest); UpsertRole(row, registeredRole, SystemCustomerRoleNames.Registered, isRegistered); UpsertRole(row, adminRole, SystemCustomerRoleNames.Administrators, isAdmin); diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/DataImporter.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/DataImporter.cs index 56906c4b8a..a45fd29155 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Import/DataImporter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/DataImporter.cs @@ -132,7 +132,7 @@ private bool HasPermission(DataImporterContext ctx) { var customer = _customerService.GetCustomerById(ctx.Request.CustomerId); - if (ctx.Request.Profile.EntityType == ImportEntityType.Product) + if (ctx.Request.Profile.EntityType == ImportEntityType.Product || ctx.Request.Profile.EntityType == ImportEntityType.Category) return _services.Permissions.Authorize(StandardPermissionProvider.ManageCatalog, customer); if (ctx.Request.Profile.EntityType == ImportEntityType.Customer) @@ -318,6 +318,9 @@ private void ImportCoreOuter(DataImporterContext ctx) _services, _subscriptionRepository.Value); } + else if (ctx.Request.Profile.EntityType == ImportEntityType.Category) + { + } else { throw new SmartException("Unsupported entity type {0}.".FormatInvariant(ctx.Request.Profile.EntityType.ToString())); diff --git a/src/Libraries/SmartStore.Services/SmartStore.Services.csproj b/src/Libraries/SmartStore.Services/SmartStore.Services.csproj index b82c8f43a1..1ad4d843a6 100644 --- a/src/Libraries/SmartStore.Services/SmartStore.Services.csproj +++ b/src/Libraries/SmartStore.Services/SmartStore.Services.csproj @@ -166,6 +166,7 @@ Properties\AssemblyVersionInfo.cs + From bfca09a0c260dcba91fcd40d4dae79bec1812000 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Fri, 18 Dec 2015 17:59:54 +0100 Subject: [PATCH 099/626] More on category import --- .../DataExchange/Import/DataImporter.cs | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/DataImporter.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/DataImporter.cs index a45fd29155..253551e629 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Import/DataImporter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/DataImporter.cs @@ -9,6 +9,7 @@ using SmartStore.Core.Domain.Customers; using SmartStore.Core.Domain.DataExchange; using SmartStore.Core.Domain.Forums; +using SmartStore.Core.Domain.Media; using SmartStore.Core.Domain.Messages; using SmartStore.Core.Domain.Seo; using SmartStore.Core.Localization; @@ -41,18 +42,21 @@ public partial class DataImporter : IDataImporter private readonly ICustomerService _customerService; private readonly Lazy> _subscriptionRepository; + private readonly Lazy> _pictureRepository; private readonly Lazy> _productPictureRepository; private readonly Lazy> _productManufacturerRepository; private readonly Lazy> _productCategoryRepository; private readonly Lazy> _urlRecordRepository; private readonly Lazy> _productRepository; private readonly Lazy> _customerRepository; + private readonly Lazy> _categoryRepository; private readonly Lazy _languageService; private readonly Lazy _localizedEntityService; private readonly Lazy _pictureService; private readonly Lazy _manufacturerService; private readonly Lazy _categoryService; + private readonly Lazy _categoryTemplateService; private readonly Lazy _productService; private readonly Lazy _urlRecordService; private readonly Lazy _storeMappingService; @@ -70,17 +74,20 @@ public DataImporter( ICommonServices services, ICustomerService customerService, Lazy> subscriptionRepository, + Lazy> pictureRepository, Lazy> productPictureRepository, Lazy> productManufacturerRepository, Lazy> productCategoryRepository, Lazy> urlRecordRepository, Lazy> productRepository, Lazy> customerRepository, + Lazy> categoryRepository, Lazy languageService, Lazy localizedEntityService, Lazy pictureService, Lazy manufacturerService, Lazy categoryService, + Lazy categoryTemplateService, Lazy productService, Lazy urlRecordService, Lazy storeMappingService, @@ -96,18 +103,21 @@ public DataImporter( _services = services; _customerService = customerService; _subscriptionRepository = subscriptionRepository; + _pictureRepository = pictureRepository; _productPictureRepository = productPictureRepository; _productManufacturerRepository = productManufacturerRepository; _productCategoryRepository = productCategoryRepository; _urlRecordRepository = urlRecordRepository; _productRepository = productRepository; _customerRepository = customerRepository; + _categoryRepository = categoryRepository; _languageService = languageService; _localizedEntityService = localizedEntityService; _pictureService = pictureService; _manufacturerService = manufacturerService; _categoryService = categoryService; + _categoryTemplateService = categoryTemplateService; _productService = productService; _urlRecordService = urlRecordService; _storeMappingService = storeMappingService; @@ -320,6 +330,16 @@ private void ImportCoreOuter(DataImporterContext ctx) } else if (ctx.Request.Profile.EntityType == ImportEntityType.Category) { + ctx.Importer = new CategoryImporter( + _categoryRepository.Value, + _urlRecordRepository.Value, + _pictureRepository.Value, + _services, + _categoryService.Value, + _urlRecordService.Value, + _categoryTemplateService.Value, + _storeMappingService.Value, + _seoSettings.Value); } else { From 2ca611c9e40cc6566d75a737210d701a1fa36082 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Fri, 18 Dec 2015 20:53:23 +0100 Subject: [PATCH 100/626] Category import: map parent id of inserted records (to build category tree) but leave parent id of updated records untouched --- .../Catalog/Importer/CategoryImporter.cs | 101 ++++++++++++++++-- .../DataExchange/Import/DataImporter.cs | 1 - 2 files changed, 92 insertions(+), 10 deletions(-) diff --git a/src/Libraries/SmartStore.Services/Catalog/Importer/CategoryImporter.cs b/src/Libraries/SmartStore.Services/Catalog/Importer/CategoryImporter.cs index 2805097bc6..8f5c066c8b 100644 --- a/src/Libraries/SmartStore.Services/Catalog/Importer/CategoryImporter.cs +++ b/src/Libraries/SmartStore.Services/Catalog/Importer/CategoryImporter.cs @@ -19,7 +19,6 @@ public class CategoryImporter : IEntityImporter private readonly IRepository _urlRecordRepository; private readonly IRepository _pictureRepository; private readonly ICommonServices _services; - private readonly ICategoryService _categoryService; private readonly IUrlRecordService _urlRecordService; private readonly ICategoryTemplateService _categoryTemplateService; private readonly IStoreMappingService _storeMappingService; @@ -30,7 +29,6 @@ public CategoryImporter( IRepository urlRecordRepository, IRepository pictureRepository, ICommonServices services, - ICategoryService categoryService, IUrlRecordService urlRecordService, ICategoryTemplateService categoryTemplateService, IStoreMappingService storeMappingService, @@ -40,7 +38,6 @@ public CategoryImporter( _urlRecordRepository = urlRecordRepository; _pictureRepository = pictureRepository; _services = services; - _categoryService = categoryService; _urlRecordService = urlRecordService; _categoryTemplateService = categoryTemplateService; _storeMappingService = storeMappingService; @@ -107,13 +104,49 @@ private int ProcessSlugs(ImportExecuteContext context, ImportRow[] bat return _urlRecordRepository.Context.SaveChanges(); } + private int ProcessParentMappings(ImportExecuteContext context, + ImportRow[] batch, + Dictionary oldToNewId) + { + object key1, key2; + + foreach (var row in batch) + { + if (row.DataRow.TryGetValue("Id", out key1) && + row.Segmenter.HasDataColumn("ParentCategoryId") && row.DataRow.TryGetValue("ParentCategoryId", out key2)) + { + var id = key1.ToString().ToInt(); + var parentId = key2.ToString().ToInt(-1); + + if (id != 0 && parentId != -1 && oldToNewId.ContainsKey(id) && oldToNewId.ContainsKey(parentId)) + { + // only touch hierarchical data if child and parent were inserted + if (oldToNewId[id].Inserted && oldToNewId[parentId].Inserted && oldToNewId[id].NewId != 0) + { + var category = _categoryRepository.GetById(oldToNewId[id].NewId); + if (category != null) + { + category.ParentCategoryId = oldToNewId[parentId].NewId; + } + } + } + } + } + + var num = _categoryRepository.Context.SaveChanges(); + + return num; + } + private int ProcessCategories(ImportExecuteContext context, ImportRow[] batch, DateTime utcNow, - List allCategoryTemplateIds) + List allCategoryTemplateIds, + Dictionary oldToNewId) { _categoryRepository.AutoCommitEnabled = true; + object key; Category lastInserted = null; Category lastUpdated = null; var defaultTemplateId = allCategoryTemplateIds.First(); @@ -121,12 +154,16 @@ private int ProcessCategories(ImportExecuteContext context, foreach (var row in batch) { Category category = null; - object key; + var id = 0; // try get by int ID - if (row.DataRow.TryGetValue("Id", out key) && key.ToString().ToInt() > 0) + if (row.DataRow.TryGetValue("Id", out key)) { - category = _categoryService.GetCategoryById(key.ToString().ToInt()); + id = key.ToString().ToInt(); + if (id != 0) + { + category = _categoryRepository.GetById(id); + } } if (category == null) @@ -160,7 +197,6 @@ private int ProcessCategories(ImportExecuteContext context, row.SetProperty(context.Result, category, (x) => x.MetaKeywords); row.SetProperty(context.Result, category, (x) => x.MetaDescription); row.SetProperty(context.Result, category, (x) => x.MetaTitle); - row.SetProperty(context.Result, category, (x) => x.ParentCategoryId); // TODO: hierachical data in batch processing? row.SetProperty(context.Result, category, (x) => x.PageSize, 12); row.SetProperty(context.Result, category, (x) => x.AllowCustomersToSelectPageSize, true); row.SetProperty(context.Result, category, (x) => x.PageSizeOptions); @@ -196,6 +232,11 @@ private int ProcessCategories(ImportExecuteContext context, row.SetProperty(context.Result, category, (x) => x.CreatedOnUtc, utcNow); category.UpdatedOnUtc = utcNow; + if (id != 0 && !oldToNewId.ContainsKey(id)) + { + oldToNewId.Add(id, new ImportCategoryMapping { Inserted = row.IsTransient }); + } + if (row.IsTransient) { _categoryRepository.Insert(category); @@ -211,6 +252,17 @@ private int ProcessCategories(ImportExecuteContext context, // commit whole batch at once var num = _categoryRepository.Context.SaveChanges(); + // get new category ids + foreach (var row in batch) + { + if (row.DataRow.TryGetValue("Id", out key)) + { + var id = key.ToString().ToInt(); + if (id != 0 && oldToNewId.ContainsKey(id)) + oldToNewId[id].NewId = row.Entity.Id; + } + } + // Perf: notify only about LAST insertion and update if (lastInserted != null) _services.EventPublisher.EntityInserted(lastInserted); @@ -222,6 +274,8 @@ private int ProcessCategories(ImportExecuteContext context, public void Execute(ImportExecuteContext context) { + var oldToNewId = new Dictionary(); + var allCategoryTemplateIds = _categoryTemplateService.GetAllCategoryTemplates() .Select(x => x.Id) .ToList(); @@ -244,7 +298,7 @@ public void Execute(ImportExecuteContext context) try { - ProcessCategories(context, batch, utcNow, allCategoryTemplateIds); + ProcessCategories(context, batch, utcNow, allCategoryTemplateIds, oldToNewId); } catch (Exception exception) { @@ -276,7 +330,36 @@ public void Execute(ImportExecuteContext context) } } } + + // map parent id of inserted categories + if (oldToNewId.Any()) + { + segmenter.Reset(); + + while (context.Abort == DataExchangeAbortion.None && segmenter.ReadNextBatch()) + { + var batch = segmenter.CurrentBatch; + + _categoryRepository.Context.DetachAll(false); + + try + { + ProcessParentMappings(context, batch, oldToNewId); + } + catch (Exception exception) + { + context.Result.AddError(exception, segmenter.CurrentSegment, "ProcessParentMappings"); + } + } + } } } } + + + internal class ImportCategoryMapping + { + public int NewId { get; set; } + public bool Inserted { get; set; } + } } diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/DataImporter.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/DataImporter.cs index 253551e629..8e79251e45 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Import/DataImporter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/DataImporter.cs @@ -335,7 +335,6 @@ private void ImportCoreOuter(DataImporterContext ctx) _urlRecordRepository.Value, _pictureRepository.Value, _services, - _categoryService.Value, _urlRecordService.Value, _categoryTemplateService.Value, _storeMappingService.Value, From f5675c6618fc5dd7b8c0ce61b32767e12d15bde1 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Sat, 19 Dec 2015 13:00:59 +0100 Subject: [PATCH 101/626] Export all product picture paths into one, pipe delimited field --- .../Catalog/Importer/ProductImporter.cs | 128 +++++++++--------- .../DataExchange/ExportExtensions.cs | 17 +++ .../DataExchange/Import/DataImporter.cs | 17 +-- .../DataExchange/Import/ImportMessage.cs | 15 +- .../DataExchange/Import/ImportResult.cs | 2 + 5 files changed, 103 insertions(+), 76 deletions(-) diff --git a/src/Libraries/SmartStore.Services/Catalog/Importer/ProductImporter.cs b/src/Libraries/SmartStore.Services/Catalog/Importer/ProductImporter.cs index 24eaa38231..231872f859 100644 --- a/src/Libraries/SmartStore.Services/Catalog/Importer/ProductImporter.cs +++ b/src/Libraries/SmartStore.Services/Catalog/Importer/ProductImporter.cs @@ -19,11 +19,11 @@ namespace SmartStore.Services.Catalog.Importer { public class ProductImporter : IEntityImporter { - private readonly IRepository _rsProductPicture; - private readonly IRepository _rsProductManufacturer; - private readonly IRepository _rsProductCategory; - private readonly IRepository _rsUrlRecord; - private readonly IRepository _rsProduct; + private readonly IRepository _productPictureRepository; + private readonly IRepository _productManufacturerRepository; + private readonly IRepository _productCategoryRepository; + private readonly IRepository _urlRecordRepository; + private readonly IRepository _productRepository; private readonly ICommonServices _services; private readonly ILanguageService _languageService; private readonly ILocalizedEntityService _localizedEntityService; @@ -36,11 +36,11 @@ public class ProductImporter : IEntityImporter private readonly SeoSettings _seoSettings; public ProductImporter( - IRepository rsProductPicture, - IRepository rsProductManufacturer, - IRepository rsProductCategory, - IRepository rsUrlRecord, - IRepository rsProduct, + IRepository productPictureRepository, + IRepository productManufacturerRepository, + IRepository productCategoryRepository, + IRepository urlRecordRepository, + IRepository productRepository, ICommonServices services, ILanguageService languageService, ILocalizedEntityService localizedEntityService, @@ -52,11 +52,11 @@ public ProductImporter( IStoreMappingService storeMappingService, SeoSettings seoSettings) { - _rsProductPicture = rsProductPicture; - _rsProductManufacturer = rsProductManufacturer; - _rsProductCategory = rsProductCategory; - _rsUrlRecord = rsUrlRecord; - _rsProduct = rsProduct; + _productPictureRepository = productPictureRepository; + _productManufacturerRepository = productManufacturerRepository; + _productCategoryRepository = productCategoryRepository; + _urlRecordRepository = urlRecordRepository; + _productRepository = productRepository; _services = services; _languageService = languageService; _localizedEntityService = localizedEntityService; @@ -82,34 +82,38 @@ public ProductImporter( private void ProcessProductPictures(ImportExecuteContext context, ImportRow[] batch) { - // true, cause pictures must be saved and assigned an id - // prior adding a mapping. - _rsProductPicture.AutoCommitEnabled = true; + // true, cause pictures must be saved and assigned an id prior adding a mapping. + _productPictureRepository.AutoCommitEnabled = true; ProductPicture lastInserted = null; - int equalPictureId = 0; + var equalPictureId = 0; foreach (var row in batch) { - var pictures = new string[] - { - row.GetDataValue("Picture1"), - row.GetDataValue("Picture2"), - row.GetDataValue("Picture3") - }; + var count = -1; + var thumbPaths = row.GetDataValue>("PictureThumbPaths"); - int i = 0; - try + if (thumbPaths == null) + continue; + + foreach (var path in thumbPaths.Where(x => x.HasValue() && File.Exists(x))) { - for (i = 0; i < pictures.Length; i++) + try { - var picture = pictures[i]; + var currentProductPictures = _productPictureRepository.TableUntracked.Expand(x => x.Picture) + .Where(x => x.ProductId == row.Entity.Id) + .ToList(); - if (picture.IsEmpty() || !File.Exists(picture)) - continue; + var currentPictures = currentProductPictures + .Select(x => x.Picture) + .ToList(); - var currentPictures = _rsProductPicture.TableUntracked.Expand(x => x.Picture).Where(x => x.ProductId == row.Entity.Id).Select(x => x.Picture).ToList(); - var pictureBinary = _pictureService.FindEqualPicture(picture, currentPictures, out equalPictureId); + if (count == -1) + { + count = (currentProductPictures.Any() ? currentProductPictures.Select(x => x.DisplayOrder).Max() : 0); + } + + var pictureBinary = _pictureService.FindEqualPicture(path, currentPictures, out equalPictureId); if (pictureBinary != null && pictureBinary.Length > 0) { @@ -121,23 +125,25 @@ private void ProcessProductPictures(ImportExecuteContext context, ImportRow[] batch) { - _rsProductManufacturer.AutoCommitEnabled = false; + _productManufacturerRepository.AutoCommitEnabled = false; ProductManufacturer lastInserted = null; @@ -160,7 +166,7 @@ private int ProcessProductManufacturers(ImportExecuteContext context, ImportRow< { foreach (var id in manufacturerIds) { - if (_rsProductManufacturer.TableUntracked.Where(x => x.ProductId == row.Entity.Id && x.ManufacturerId == id).FirstOrDefault() == null) + if (_productManufacturerRepository.TableUntracked.Where(x => x.ProductId == row.Entity.Id && x.ManufacturerId == id).FirstOrDefault() == null) { // ensure that manufacturer exists var manufacturer = _manufacturerService.GetManufacturerById(id); @@ -173,7 +179,7 @@ private int ProcessProductManufacturers(ImportExecuteContext context, ImportRow< IsFeaturedProduct = false, DisplayOrder = 1 }; - _rsProductManufacturer.Insert(productManufacturer); + _productManufacturerRepository.Insert(productManufacturer); lastInserted = productManufacturer; } } @@ -187,7 +193,7 @@ private int ProcessProductManufacturers(ImportExecuteContext context, ImportRow< } // commit whole batch at once - var num = _rsProductManufacturer.Context.SaveChanges(); + var num = _productManufacturerRepository.Context.SaveChanges(); // Perf: notify only about LAST insertion and update if (lastInserted != null) @@ -198,7 +204,7 @@ private int ProcessProductManufacturers(ImportExecuteContext context, ImportRow< private int ProcessProductCategories(ImportExecuteContext context, ImportRow[] batch) { - _rsProductCategory.AutoCommitEnabled = false; + _productCategoryRepository.AutoCommitEnabled = false; ProductCategory lastInserted = null; @@ -211,7 +217,7 @@ private int ProcessProductCategories(ImportExecuteContext context, ImportRow x.ProductId == row.Entity.Id && x.CategoryId == id).FirstOrDefault() == null) + if (_productCategoryRepository.TableUntracked.Where(x => x.ProductId == row.Entity.Id && x.CategoryId == id).FirstOrDefault() == null) { // ensure that category exists var category = _categoryService.GetCategoryById(id); @@ -224,7 +230,7 @@ private int ProcessProductCategories(ImportExecuteContext context, ImportRow[] batc LanguageId = 0, IsActive = true, }; - _rsUrlRecord.Insert(urlRecord); + _urlRecordRepository.Insert(urlRecord); } else { @@ -358,12 +364,12 @@ private int ProcessSlugs(ImportExecuteContext context, ImportRow[] batc } // commit whole batch at once - return _rsUrlRecord.Context.SaveChanges(); + return _urlRecordRepository.Context.SaveChanges(); } private int ProcessProducts(ImportExecuteContext context, ImportRow[] batch, DateTime utcNow) { - _rsProduct.AutoCommitEnabled = true; + _productRepository.AutoCommitEnabled = true; Product lastInserted = null; Product lastUpdated = null; @@ -510,18 +516,18 @@ private int ProcessProducts(ImportExecuteContext context, ImportRow[] b if (row.IsTransient) { - _rsProduct.Insert(product); + _productRepository.Insert(product); lastInserted = product; } else { - _rsProduct.Update(product); + _productRepository.Update(product); lastUpdated = product; } } // commit whole batch at once - var num = _rsProduct.Context.SaveChanges(); + var num = _productRepository.Context.SaveChanges(); // Perf: notify only about LAST insertion and update if (lastInserted != null) @@ -534,7 +540,7 @@ private int ProcessProducts(ImportExecuteContext context, ImportRow[] b public void Execute(ImportExecuteContext context) { - using (var scope = new DbContextScope(ctx: _rsProduct.Context, autoDetectChanges: false, proxyCreation: false, validateOnSave: false)) + using (var scope = new DbContextScope(ctx: _productRepository.Context, autoDetectChanges: false, proxyCreation: false, validateOnSave: false)) { var segmenter = new ImportDataSegmenter(context.DataTable); var utcNow = DateTime.UtcNow; @@ -546,7 +552,7 @@ public void Execute(ImportExecuteContext context) var batch = segmenter.CurrentBatch; // Perf: detach all entities - _rsProduct.Context.DetachAll(false); + _productRepository.Context.DetachAll(false); context.SetProgress(segmenter.CurrentSegmentFirstRowIndex - 1, segmenter.TotalRows); @@ -579,7 +585,7 @@ public void Execute(ImportExecuteContext context) { try { - _rsProduct.Context.AutoDetectChangesEnabled = true; + _productRepository.Context.AutoDetectChangesEnabled = true; ProcessSlugs(context, batch); } catch (Exception exception) @@ -588,7 +594,7 @@ public void Execute(ImportExecuteContext context) } finally { - _rsProduct.Context.AutoDetectChangesEnabled = false; + _productRepository.Context.AutoDetectChangesEnabled = false; } } @@ -637,7 +643,7 @@ public void Execute(ImportExecuteContext context) // =========================================================================== // 6.) Import product picture mappings // =========================================================================== - if (context.DataTable.HasColumn("Picture1") || context.DataTable.HasColumn("Picture2") || context.DataTable.HasColumn("Picture3")) + if (context.DataTable.HasColumn("PictureThumbPaths")) { try { diff --git a/src/Libraries/SmartStore.Services/DataExchange/ExportExtensions.cs b/src/Libraries/SmartStore.Services/DataExchange/ExportExtensions.cs index 3d65d673c8..a0c9f14dcc 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/ExportExtensions.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/ExportExtensions.cs @@ -128,5 +128,22 @@ public static string ResolveFileNamePattern(this ExportProfile profile, Store st return result; } + + /// + /// Join values into a string that can be used for exporting + /// + /// Type + /// Enumerable of values to join + /// Joined values + public static string JoinForExport(this IEnumerable values) + { + if (values == null) + return ""; + + if (typeof(T) == typeof(string)) + return string.Join("|", values); // because file paths cannot contain pipes + + return string.Join(",", values); + } } } diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/DataImporter.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/DataImporter.cs index 8e79251e45..3a081417a1 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Import/DataImporter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/DataImporter.cs @@ -176,23 +176,12 @@ private void LogResult(DataImporterContext ctx) foreach (var message in result.Messages) { - string prefix = null; - - if (message.AffectedItem != null) - prefix.Grow("Pos: " + (message.AffectedItem.Position + 1).ToString(), ", "); - - if (message.AffectedField.HasValue()) - prefix.Grow("Field: " + message.AffectedField, ", "); - - if (prefix.HasValue()) - message.Message = "[{0}] {1}".FormatInvariant(prefix, message.Message); - if (message.MessageType == ImportMessageType.Error) - ctx.Log.Error(message.Message); + ctx.Log.Error(message.ToString()); else if (message.MessageType == ImportMessageType.Warning) - ctx.Log.Warning(message.Message); + ctx.Log.Warning(message.ToString()); else - ctx.Log.Information(message.Message); + ctx.Log.Information(message.ToString()); } } diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportMessage.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportMessage.cs index 245aabc173..7285a6a52b 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportMessage.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportMessage.cs @@ -39,7 +39,20 @@ public string Message public override string ToString() { - return "{0} - {1}".FormatCurrent(MessageType.ToString().ToUpper(), Message.EmptyNull()); + var result = Message.NaIfEmpty(); + + string appendix = null; + + if (AffectedItem != null) + appendix = appendix.Grow("Pos: " + (AffectedItem.Position + 1).ToString(), ", "); + + if (AffectedField.HasValue()) + appendix = appendix.Grow("Field: " + AffectedField, ", "); + + if (appendix.HasValue()) + result = "{0} [{1}]".FormatInvariant(result, appendix); + + return result; } } diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportResult.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportResult.cs index 7e52d3948e..d648387876 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportResult.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportResult.cs @@ -106,8 +106,10 @@ public ImportMessage AddError(Exception exception, int? affectedBatch = null, st public ImportMessage AddMessage(string message, ImportMessageType severity, ImportRowInfo affectedRow = null, string affectedField = null) { var msg = new ImportMessage(message, severity); + msg.AffectedItem = affectedRow; msg.AffectedField = affectedField; + this.Messages.Add(msg); return msg; } From 75467a75057405817bfe14808c776a31f2d3c8bc Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Sat, 19 Dec 2015 16:46:29 +0100 Subject: [PATCH 102/626] Category import: Treat picture as in product import thus exchange the local picture path --- .../Catalog/Importer/CategoryImporter.cs | 34 +++++++++++++++---- .../DataExchange/Import/DataImporter.cs | 1 + .../Media/IPictureService.cs | 17 +++++----- .../Media/PictureService.cs | 18 +++++----- 4 files changed, 45 insertions(+), 25 deletions(-) diff --git a/src/Libraries/SmartStore.Services/Catalog/Importer/CategoryImporter.cs b/src/Libraries/SmartStore.Services/Catalog/Importer/CategoryImporter.cs index 8f5c066c8b..233a36e638 100644 --- a/src/Libraries/SmartStore.Services/Catalog/Importer/CategoryImporter.cs +++ b/src/Libraries/SmartStore.Services/Catalog/Importer/CategoryImporter.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using SmartStore.Core.Data; using SmartStore.Core.Domain.Catalog; @@ -8,6 +9,7 @@ using SmartStore.Core.Domain.Seo; using SmartStore.Core.Events; using SmartStore.Services.DataExchange.Import; +using SmartStore.Services.Media; using SmartStore.Services.Seo; using SmartStore.Services.Stores; @@ -22,6 +24,7 @@ public class CategoryImporter : IEntityImporter private readonly IUrlRecordService _urlRecordService; private readonly ICategoryTemplateService _categoryTemplateService; private readonly IStoreMappingService _storeMappingService; + private readonly IPictureService _pictureService; private readonly SeoSettings _seoSettings; public CategoryImporter( @@ -32,6 +35,7 @@ public CategoryImporter( IUrlRecordService urlRecordService, ICategoryTemplateService categoryTemplateService, IStoreMappingService storeMappingService, + IPictureService pictureService, SeoSettings seoSettings) { _categoryRepository = categoryRepository; @@ -41,6 +45,7 @@ public CategoryImporter( _urlRecordService = urlRecordService; _categoryTemplateService = categoryTemplateService; _storeMappingService = storeMappingService; + _pictureService = pictureService; _seoSettings = seoSettings; } @@ -147,8 +152,10 @@ private int ProcessCategories(ImportExecuteContext context, _categoryRepository.AutoCommitEnabled = true; object key; + Picture picture = null; Category lastInserted = null; Category lastUpdated = null; + var equalPictureId = 0; var defaultTemplateId = allCategoryTemplateIds.First(); foreach (var row in batch) @@ -216,19 +223,32 @@ private int ProcessCategories(ImportExecuteContext context, category.CategoryTemplateId = templateId; } - if (row.DataRow.TryGetValue("PictureId", out key)) - { - int pictureId = key.ToString().ToInt(); - if (pictureId > 0 && _pictureRepository.TableUntracked.Any(x => x.Id == pictureId)) - category.PictureId = pictureId; - } - var storeIds = row.GetDataValue>("StoreIds"); if (storeIds != null && storeIds.Any()) { _storeMappingService.SaveStoreMappings(category, storeIds.ToArray()); } + if (row.DataRow.TryGetValue("PictureThumbPath", out key)) + { + var thumbPath = key.ToString(); + if (thumbPath.HasValue() && File.Exists(thumbPath)) + { + var pictures = new List(); + if (category.PictureId.HasValue && (picture = _pictureRepository.GetById(category.PictureId.Value)) != null) + pictures.Add(picture); + + var pictureBinary = _pictureService.FindEqualPicture(thumbPath, pictures, out equalPictureId); + + if (pictureBinary != null && pictureBinary.Length > 0 && + (picture = _pictureService.InsertPicture(pictureBinary, "image/jpeg", _pictureService.GetPictureSeName(row.EntityDisplayName), true, false, false)) != null) + { + category.PictureId = picture.Id; + } + } + } + + row.SetProperty(context.Result, category, (x) => x.CreatedOnUtc, utcNow); category.UpdatedOnUtc = utcNow; diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/DataImporter.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/DataImporter.cs index 3a081417a1..b455823401 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Import/DataImporter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/DataImporter.cs @@ -327,6 +327,7 @@ private void ImportCoreOuter(DataImporterContext ctx) _urlRecordService.Value, _categoryTemplateService.Value, _storeMappingService.Value, + _pictureService.Value, _seoSettings.Value); } else diff --git a/src/Libraries/SmartStore.Services/Media/IPictureService.cs b/src/Libraries/SmartStore.Services/Media/IPictureService.cs index 85bc1741b5..ce9f231349 100644 --- a/src/Libraries/SmartStore.Services/Media/IPictureService.cs +++ b/src/Libraries/SmartStore.Services/Media/IPictureService.cs @@ -5,10 +5,10 @@ namespace SmartStore.Services.Media { - /// - /// Picture service interface - /// - public partial interface IPictureService + /// + /// Picture service interface + /// + public partial interface IPictureService { /// /// Validates input picture dimensions and prevents that the image size exceeds global max size @@ -22,20 +22,19 @@ public partial interface IPictureService /// Finds an equal picture by comparing the binary buffer /// /// The picture to find a duplicate for - /// The sequence of product pictures to seek within for duplicates + /// The sequence of pictures to seek within for duplicates /// Id of equal picture if any /// The picture binary for path when no picture equals in the sequence, null otherwise. - byte[] FindEqualPicture(string path, IEnumerable productPictures, out int equalPictureId); + byte[] FindEqualPicture(string path, IEnumerable pictures, out int equalPictureId); /// /// Finds an equal picture by comparing the binary buffer /// /// Binary picture data - /// The sequence of product pictures to seek within for duplicates + /// The sequence of pictures to seek within for duplicates /// Id of equal picture if any /// The picture binary for path when no picture equals in the sequence, null otherwise. - byte[] FindEqualPicture(byte[] pictureBinary, IEnumerable productPictures, out int equalPictureId); - + byte[] FindEqualPicture(byte[] pictureBinary, IEnumerable pictures, out int equalPictureId); /// /// Gets the loaded picture binary depending on picture storage settings diff --git a/src/Libraries/SmartStore.Services/Media/PictureService.cs b/src/Libraries/SmartStore.Services/Media/PictureService.cs index 95c58fb845..563993234f 100644 --- a/src/Libraries/SmartStore.Services/Media/PictureService.cs +++ b/src/Libraries/SmartStore.Services/Media/PictureService.cs @@ -154,17 +154,21 @@ public virtual byte[] ValidatePicture(byte[] pictureBinary) } } - public byte[] FindEqualPicture(string path, IEnumerable productPictures, out int equalPictureId) + #endregion + + #region Methods + + public byte[] FindEqualPicture(string path, IEnumerable pictures, out int equalPictureId) { - return FindEqualPicture(File.ReadAllBytes(path), productPictures, out equalPictureId); + return FindEqualPicture(File.ReadAllBytes(path), pictures, out equalPictureId); } - public byte[] FindEqualPicture(byte[] pictureBinary, IEnumerable productPictures, out int equalPictureId) + public byte[] FindEqualPicture(byte[] pictureBinary, IEnumerable pictures, out int equalPictureId) { equalPictureId = 0; try { - foreach (var picture in productPictures) + foreach (var picture in pictures) { var otherPictureBinary = LoadPictureBinary(picture); @@ -187,11 +191,7 @@ public byte[] FindEqualPicture(byte[] pictureBinary, IEnumerable produc } } - #endregion - - #region Methods - - public virtual string GetPictureSeName(string name) + public virtual string GetPictureSeName(string name) { return SeoHelper.GetSeName(name, true, false); } From 1f2343125dc621ad95bc880abbb6803977007630 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Sun, 20 Dec 2015 13:01:25 +0100 Subject: [PATCH 103/626] Extended data import column mapping --- .../DataExchange/ColumnMap.cs | 67 ++++++++++++------- .../Import/ImportDataSegmenter.cs | 4 +- .../DataExchange/Import/ImportRow.cs | 26 +++++-- 3 files changed, 67 insertions(+), 30 deletions(-) diff --git a/src/Libraries/SmartStore.Services/DataExchange/ColumnMap.cs b/src/Libraries/SmartStore.Services/DataExchange/ColumnMap.cs index 5149e2c6d8..f602b1238b 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/ColumnMap.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/ColumnMap.cs @@ -1,69 +1,80 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace SmartStore.Services.DataExchange { public class ColumnMap { - private readonly Dictionary _map = new Dictionary(StringComparer.OrdinalIgnoreCase); + private readonly Dictionary _map = new Dictionary(StringComparer.OrdinalIgnoreCase); - public IReadOnlyDictionary Mappings + public IReadOnlyDictionary Mappings { get { return _map; } } - public void AddMapping(string sourceName, string mappedName) + public void AddMapping(string sourceName, string entityProperty, string defaultValue = null) { - AddMapping(sourceName, null, mappedName); + AddMapping(sourceName, null, entityProperty, defaultValue); } - public void AddMapping(string sourceName, string index, string mappedName) + public void AddMapping(string sourceName, string index, string entityProperty, string defaultValue = null) { Guard.ArgumentNotEmpty(() => sourceName); - Guard.ArgumentNotEmpty(() => mappedName); + Guard.ArgumentNotEmpty(() => entityProperty); - _map[CreateName(sourceName, index)] = mappedName; + _map[CreateSourceName(sourceName, index)] = new ColumnMappingValue + { + EntityProperty = entityProperty, + DefaultValue = defaultValue + }; } /// - /// Gets a mapped column name + /// Gets a mapped column value /// - /// The name of the column to get a mapped name for. - /// The mapped column name OR - if the name is unmapped - the passed - public string GetMappedName(string sourceName) + /// The name of the column to get a mapped value for. + /// The mapped column name OR - if the name is unmapped - a value with the passed + public ColumnMappingValue GetMapping(string sourceName) { - string result; + ColumnMappingValue result; + if (_map.TryGetValue(sourceName, out result)) { return result; } - return sourceName; + return new ColumnMappingValue { EntityProperty = sourceName }; } /// - /// Gets a mapped column name + /// Gets a mapped column value /// - /// The name of the column to get a mapped name for. + /// The name of the column to get a mapped value for. /// The column index, e.g. a language code (de, en etc.) - /// The mapped column name OR - if the name is unmapped - the passed [] - public string GetMappedName(string sourceName, string index) + /// The mapped column name OR - if the name is unmapped - a value with the passed [] + public ColumnMappingValue GetMapping(string sourceName, string index) + { + return GetMapping(CreateSourceName(sourceName, index)); + } + + public string GetMappedProperty(string sourceName) { - sourceName = CreateName(sourceName, index); + ColumnMappingValue result; - string result; if (_map.TryGetValue(sourceName, out result)) { - return result; + return result.EntityProperty; } return sourceName; } - internal static string CreateName(string name, string index) + public string GetMappedProperty(string sourceName, string index) + { + return GetMappedProperty(CreateSourceName(sourceName, index)); + } + + internal static string CreateSourceName(string name, string index) { if (index.HasValue()) { @@ -73,4 +84,12 @@ internal static string CreateName(string name, string index) return name; } } + + + public class ColumnMappingValue + { + public string EntityProperty { get; set; } + + public string DefaultValue { get; set; } + } } diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportDataSegmenter.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportDataSegmenter.cs index 4bcb355089..d9ecad1d7b 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportDataSegmenter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportDataSegmenter.cs @@ -89,12 +89,12 @@ public int BatchSize public bool HasDataColumn(string name) { - return _table.HasColumn(_columnMap.GetMappedName(name)); + return _table.HasColumn(_columnMap.GetMappedProperty(name)); } public bool HasDataColumn(string name, string index) { - return _table.HasColumn(_columnMap.GetMappedName(name, index)); + return _table.HasColumn(_columnMap.GetMappedProperty(name, index)); } /// diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportRow.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportRow.cs index 5b469a9352..da18417c95 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportRow.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportRow.cs @@ -91,7 +91,7 @@ public TProp GetDataValue(string columnName) public TProp GetDataValue(string columnName, string index) { object value; - if (_row.TryGetValue(_segmenter.ColumnMap.GetMappedName(columnName, index), out value)) + if (_row.TryGetValue(_segmenter.ColumnMap.GetMappedProperty(columnName, index), out value)) { return value.Convert(_segmenter.Culture); } @@ -117,7 +117,25 @@ public bool SetProperty( var fastProp = FastProperty.GetProperty(target.GetUnproxiedType(), propName, PropertyCachingStrategy.EagerCached); object value; - if (_row.TryGetValue(_segmenter.ColumnMap.GetMappedName(propName), out value)) + var mapping = _segmenter.ColumnMap.GetMapping(propName); + + if (mapping.DefaultValue != null) + { + try + { + if (mapping.DefaultValue.IsEmpty()) + defaultValue = default(TProp); // ignore called in value and explicitly convert to default + else + defaultValue = mapping.DefaultValue.Convert(_segmenter.Culture); + } + catch (Exception exception) + { + var msg = "Failed to convert default value '{0}'. Please specify a convertable default value. {1}"; + result.AddWarning(msg.FormatInvariant(mapping.DefaultValue.NaIfEmpty(), exception.Message), this.GetRowInfo(), propName); + } + } + + if (_row.TryGetValue(mapping.EntityProperty, out value)) { // source contains field value. Set it. TProp converted; @@ -147,9 +165,9 @@ public bool SetProperty( } } } - catch (Exception ex) + catch (Exception exception) { - result.AddWarning("Conversion failed: " + ex.Message, this.GetRowInfo(), propName); + result.AddWarning("Conversion failed: " + exception.Message, this.GetRowInfo(), propName); } return false; From 85e62269dc15eec4cfee40ed40d42db620d573c1 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Mon, 21 Dec 2015 12:41:31 +0100 Subject: [PATCH 104/626] Getting started with import column mapping --- .../DataExchange/ColumnMap.cs | 95 --------------- .../Import/ColumnMapping/ColumnMap.cs | 112 ++++++++++++++++++ .../ColumnMapping}/ColumnMapConverter.cs | 15 ++- .../SmartStore.Services.csproj | 4 +- .../Controllers/ImportController.cs | 109 ++++++++++++++--- .../Infrastructure/AdminStartupTask.cs | 2 +- .../Models/DataExchange/ImportProfileModel.cs | 15 +++ .../Administration/SmartStore.Admin.csproj | 1 + .../Views/Import/_ColumnMappings.cshtml | 7 ++ .../Views/Import/_CreateOrUpdate.cshtml | 2 + 10 files changed, 249 insertions(+), 113 deletions(-) delete mode 100644 src/Libraries/SmartStore.Services/DataExchange/ColumnMap.cs create mode 100644 src/Libraries/SmartStore.Services/DataExchange/Import/ColumnMapping/ColumnMap.cs rename src/Libraries/SmartStore.Services/DataExchange/{ => Import/ColumnMapping}/ColumnMapConverter.cs (77%) create mode 100644 src/Presentation/SmartStore.Web/Administration/Views/Import/_ColumnMappings.cshtml diff --git a/src/Libraries/SmartStore.Services/DataExchange/ColumnMap.cs b/src/Libraries/SmartStore.Services/DataExchange/ColumnMap.cs deleted file mode 100644 index f602b1238b..0000000000 --- a/src/Libraries/SmartStore.Services/DataExchange/ColumnMap.cs +++ /dev/null @@ -1,95 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace SmartStore.Services.DataExchange -{ - public class ColumnMap - { - private readonly Dictionary _map = new Dictionary(StringComparer.OrdinalIgnoreCase); - - public IReadOnlyDictionary Mappings - { - get { return _map; } - } - - public void AddMapping(string sourceName, string entityProperty, string defaultValue = null) - { - AddMapping(sourceName, null, entityProperty, defaultValue); - } - - public void AddMapping(string sourceName, string index, string entityProperty, string defaultValue = null) - { - Guard.ArgumentNotEmpty(() => sourceName); - Guard.ArgumentNotEmpty(() => entityProperty); - - _map[CreateSourceName(sourceName, index)] = new ColumnMappingValue - { - EntityProperty = entityProperty, - DefaultValue = defaultValue - }; - } - - /// - /// Gets a mapped column value - /// - /// The name of the column to get a mapped value for. - /// The mapped column name OR - if the name is unmapped - a value with the passed - public ColumnMappingValue GetMapping(string sourceName) - { - ColumnMappingValue result; - - if (_map.TryGetValue(sourceName, out result)) - { - return result; - } - - return new ColumnMappingValue { EntityProperty = sourceName }; - } - - /// - /// Gets a mapped column value - /// - /// The name of the column to get a mapped value for. - /// The column index, e.g. a language code (de, en etc.) - /// The mapped column name OR - if the name is unmapped - a value with the passed [] - public ColumnMappingValue GetMapping(string sourceName, string index) - { - return GetMapping(CreateSourceName(sourceName, index)); - } - - public string GetMappedProperty(string sourceName) - { - ColumnMappingValue result; - - if (_map.TryGetValue(sourceName, out result)) - { - return result.EntityProperty; - } - - return sourceName; - } - - public string GetMappedProperty(string sourceName, string index) - { - return GetMappedProperty(CreateSourceName(sourceName, index)); - } - - internal static string CreateSourceName(string name, string index) - { - if (index.HasValue()) - { - name += String.Concat("[", index, "]"); - } - - return name; - } - } - - - public class ColumnMappingValue - { - public string EntityProperty { get; set; } - - public string DefaultValue { get; set; } - } -} diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/ColumnMapping/ColumnMap.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/ColumnMapping/ColumnMap.cs new file mode 100644 index 0000000000..b7f588d487 --- /dev/null +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/ColumnMapping/ColumnMap.cs @@ -0,0 +1,112 @@ +using System; +using System.Collections.Generic; + +namespace SmartStore.Services.DataExchange.Import +{ + public class ColumnMap + { + private readonly Dictionary _map = new Dictionary(StringComparer.OrdinalIgnoreCase); + + public IReadOnlyDictionary Mappings + { + get { return _map; } + } + + public void AddMapping(string sourceColumn, string entityProperty, string defaultValue = null) + { + AddMapping(sourceColumn, null, entityProperty, defaultValue); + } + + public void AddMapping(string sourceColumn, string index, string entityProperty, string defaultValue = null) + { + Guard.ArgumentNotEmpty(() => sourceColumn); + Guard.ArgumentNotEmpty(() => entityProperty); + + _map[CreateSourceName(sourceColumn, index)] = new ColumnMappingValue + { + EntityProperty = entityProperty, + DefaultValue = defaultValue + }; + } + + /// + /// Gets a mapped column value + /// + /// The name of the column to get a mapped value for. + /// The mapped column value OR - if the name is unmapped - a value with the passed + public ColumnMappingValue GetMapping(string sourceColumn) + { + ColumnMappingValue result; + + if (_map.TryGetValue(sourceColumn, out result)) + { + return result; + } + + return new ColumnMappingValue { EntityProperty = sourceColumn }; + } + + /// + /// Gets a mapped column value + /// + /// The name of the column to get a mapped value for. + /// The column index, e.g. a language code (de, en etc.) + /// The mapped column value OR - if the name is unmapped - a value with the passed [] + public ColumnMappingValue GetMapping(string sourceColumn, string index) + { + return GetMapping(CreateSourceName(sourceColumn, index)); + } + + /// + /// Gets a mapped property name + /// + /// The name of the column to get a mapped property name for. + /// The mapped property name OR - if the name is unmapped - the passed [] + public string GetMappedProperty(string sourceColumn) + { + ColumnMappingValue result; + + if (_map.TryGetValue(sourceColumn, out result)) + { + return result.EntityProperty; + } + + return sourceColumn; + } + + /// + /// Gets a mapped property name + /// + /// The name of the column to get a mapped property name for. + /// The column index, e.g. a language code (de, en etc.) + /// The mapped property name OR - if the name is unmapped - the passed [] + public string GetMappedProperty(string sourceColumn, string index) + { + return GetMappedProperty(CreateSourceName(sourceColumn, index)); + } + + internal static string CreateSourceName(string name, string index) + { + if (index.HasValue()) + { + name += String.Concat("[", index, "]"); + } + + return name; + } + } + + + public class ColumnMappingValue + { + /// + /// The property name of the target entity + /// + public string EntityProperty { get; set; } + + /// + /// An optional default value + /// + public string DefaultValue { get; set; } + } +} diff --git a/src/Libraries/SmartStore.Services/DataExchange/ColumnMapConverter.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/ColumnMapping/ColumnMapConverter.cs similarity index 77% rename from src/Libraries/SmartStore.Services/DataExchange/ColumnMapConverter.cs rename to src/Libraries/SmartStore.Services/DataExchange/Import/ColumnMapping/ColumnMapConverter.cs index 0fa97b26f0..12f251bd4d 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/ColumnMapConverter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/ColumnMapping/ColumnMapConverter.cs @@ -4,7 +4,7 @@ using Newtonsoft.Json; using SmartStore.ComponentModel; -namespace SmartStore.Services.DataExchange +namespace SmartStore.Services.DataExchange.Import { public class ColumnMapConverter : TypeConverterBase { @@ -41,6 +41,14 @@ public override object ConvertFrom(CultureInfo culture, object value) return base.ConvertFrom(culture, value); } + public T ConvertFrom(string value) + { + if (value.HasValue()) + return (T)ConvertFrom(CultureInfo.InvariantCulture, value); + + return default(T); + } + public override object ConvertTo(CultureInfo culture, string format, object value, Type to) { if (to == typeof(string)) @@ -57,5 +65,10 @@ public override object ConvertTo(CultureInfo culture, string format, object valu return base.ConvertTo(culture, format, value, to); } + + public string ConvertTo(object value) + { + return (string)ConvertTo(CultureInfo.InvariantCulture, null, value, typeof(string)); + } } } diff --git a/src/Libraries/SmartStore.Services/SmartStore.Services.csproj b/src/Libraries/SmartStore.Services/SmartStore.Services.csproj index 1ad4d843a6..405df35f5a 100644 --- a/src/Libraries/SmartStore.Services/SmartStore.Services.csproj +++ b/src/Libraries/SmartStore.Services/SmartStore.Services.csproj @@ -174,8 +174,8 @@ - - + + diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs index e38db2e8b3..af761f78d9 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs @@ -45,8 +45,68 @@ public ImportController( #region Utilities + private List PrepareColumnMappingModels(ImportProfile profile, CsvConfiguration csvConfiguration) + { + var models = new List(); + + try + { + var mapConverter = new ColumnMapConverter(); + var map = mapConverter.ConvertFrom(profile.ColumnMapping); + + if (map != null && map.Mappings.Any()) + { + models = map.Mappings + .Select(x => + { + var mapModel = new ColumnMappingItemModel + { + SourceColumn = x.Key, + EntityProperty = x.Value.EntityProperty, + DefaultValue = x.Value.DefaultValue + }; + return mapModel; + }) + .ToList(); + } + else + { + var files = profile.GetImportFiles(); + if (files.Any()) + { + var filePath = files.First(); + using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) + { + var dataTable = LightweightDataTable.FromFile(Path.GetFileName(filePath), stream, stream.Length, csvConfiguration, 0, 2); + + foreach (var column in dataTable.Columns) + { + models.Add(new ColumnMappingItemModel + { + SourceColumn = column.Name + }); + } + + return models; + } + } + } + } + catch (Exception exception) + { + NotifyError(exception); + } + return models; + } + private void PrepareProfileModel(ImportProfileModel model, ImportProfile profile, bool forEdit) { + if (forEdit) + { + model.AvailableEntityTypes = ImportEntityType.Product.ToSelectList(false).ToList(); + model.AvailableFileTypes = ImportFileType.CSV.ToSelectList(false).ToList(); + } + if (profile != null) { model.Id = profile.Id; @@ -67,12 +127,19 @@ private void PrepareProfileModel(ImportProfileModel model, ImportProfile profile .Select(x => Path.GetFileName(x)) .ToList(); - if (profile.FileType == ImportFileType.CSV) + if (forEdit) { - var converter = new CsvConfigurationConverter(); - var config = converter.ConvertFrom(profile.FileTypeConfiguration); + CsvConfiguration csvConfiguration = null; + + if (profile.FileType == ImportFileType.CSV) + { + var csvConverter = new CsvConfigurationConverter(); + csvConfiguration = csvConverter.ConvertFrom(profile.FileTypeConfiguration); + + model.CsvConfiguration = new CsvConfigurationModel(csvConfiguration ?? CsvConfiguration.ExcelFriendlyConfiguration); + } - model.CsvConfiguration = new CsvConfigurationModel(config ?? CsvConfiguration.ExcelFriendlyConfiguration); + model.ColumnMappings = PrepareColumnMappingModels(profile, csvConfiguration); } } else @@ -80,12 +147,6 @@ private void PrepareProfileModel(ImportProfileModel model, ImportProfile profile model.Name = model.EntityType.GetLocalizedEnum(_services.Localization, _services.WorkContext); model.ExistingFileNames = new List(); } - - if (forEdit) - { - model.AvailableEntityTypes = ImportEntityType.Product.ToSelectList(false).ToList(); - model.AvailableFileTypes = ImportFileType.CSV.ToSelectList(false).ToList(); - } } #endregion @@ -192,12 +253,32 @@ public ActionResult Edit(ImportProfileModel model, bool continueEditing, FormCol profile.Skip = model.Skip; profile.Take = model.Take; - if (profile.FileType == ImportFileType.CSV && model.CsvConfiguration != null) + if (model.ColumnMappings != null && model.ColumnMappings.Any()) + { + var map = new ColumnMap(); + var mapConverter = new ColumnMapConverter(); + + model.ColumnMappings.Each(x => map.AddMapping(x.SourceColumn, x.EntityProperty, x.DefaultValue)); + profile.ColumnMapping = mapConverter.ConvertTo(map); + } + else + { + profile.ColumnMapping = null; + } + + if (profile.FileType == ImportFileType.CSV) { - CsvConfiguration config = model.CsvConfiguration.Clone(); + if (model.CsvConfiguration != null) + { + CsvConfiguration config = model.CsvConfiguration.Clone(); - var converter = new CsvConfigurationConverter(); - profile.FileTypeConfiguration = converter.ConvertTo(config); + var csvConverter = new CsvConfigurationConverter(); + profile.FileTypeConfiguration = csvConverter.ConvertTo(config); + } + else + { + profile.FileTypeConfiguration = null; + } } _importService.UpdateImportProfile(profile); diff --git a/src/Presentation/SmartStore.Web/Administration/Infrastructure/AdminStartupTask.cs b/src/Presentation/SmartStore.Web/Administration/Infrastructure/AdminStartupTask.cs index fd624d63ce..c9f1b6ef7e 100644 --- a/src/Presentation/SmartStore.Web/Administration/Infrastructure/AdminStartupTask.cs +++ b/src/Presentation/SmartStore.Web/Administration/Infrastructure/AdminStartupTask.cs @@ -1,7 +1,7 @@ using SmartStore.ComponentModel; using SmartStore.Core.Infrastructure; -using SmartStore.Services.DataExchange; using SmartStore.Services.DataExchange.Csv; +using SmartStore.Services.DataExchange.Import; namespace SmartStore.Admin.Infrastructure { diff --git a/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ImportProfileModel.cs b/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ImportProfileModel.cs index 76cc11caff..9f512f4ec5 100644 --- a/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ImportProfileModel.cs +++ b/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ImportProfileModel.cs @@ -47,5 +47,20 @@ public partial class ImportProfileModel : EntityModelBase public string TempFileName { get; set; } public CsvConfigurationModel CsvConfiguration { get; set; } + public List ColumnMappings { get; set; } + } + + + public class ColumnMappingItemModel + { + [SmartResourceDisplayName("Admin.DataExchange.ColumnMapping.SourceColumn")] + public string SourceColumn { get; set; } + + [SmartResourceDisplayName("Admin.DataExchange.ColumnMapping.EntityProperty")] + public string EntityProperty { get; set; } + public List AvailableEntityProperties { get; set; } + + [SmartResourceDisplayName("Admin.DataExchange.ColumnMapping.DefaultValue")] + public string DefaultValue { get; set; } } } \ No newline at end of file diff --git a/src/Presentation/SmartStore.Web/Administration/SmartStore.Admin.csproj b/src/Presentation/SmartStore.Web/Administration/SmartStore.Admin.csproj index b850530104..5b0852f437 100644 --- a/src/Presentation/SmartStore.Web/Administration/SmartStore.Admin.csproj +++ b/src/Presentation/SmartStore.Web/Administration/SmartStore.Admin.csproj @@ -544,6 +544,7 @@ + diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Import/_ColumnMappings.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Import/_ColumnMappings.cshtml new file mode 100644 index 0000000000..8492e891f4 --- /dev/null +++ b/src/Presentation/SmartStore.Web/Administration/Views/Import/_ColumnMappings.cshtml @@ -0,0 +1,7 @@ +@using SmartStore.Admin.Models.DataExchange; +@model ImportProfileModel +
+ @foreach (var mapping in Model.ColumnMappings) + { + } +
\ No newline at end of file diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Import/_CreateOrUpdate.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Import/_CreateOrUpdate.cshtml index c479639b6b..7724afcf8e 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Import/_CreateOrUpdate.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Import/_CreateOrUpdate.cshtml @@ -130,6 +130,8 @@ @Html.Partial("CsvConfiguration", Model.CsvConfiguration, viewData) } +@Html.Partial("_ColumnMappings") + \ No newline at end of file From 69e20c822984225d80c9389e6c893fe6bc567876 Mon Sep 17 00:00:00 2001 From: Michael Herzog Date: Tue, 22 Dec 2015 16:21:14 +0100 Subject: [PATCH 107/626] Closes #815 Spelling: Import Summary message: Admin.Common.ImportFromExcel.QuickStats --- .../SmartStore.Data/Migrations/201403262015448_ImportExcel.cs | 2 +- .../SmartStore.Web/App_Data/Localization/App/en/all.smres.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Libraries/SmartStore.Data/Migrations/201403262015448_ImportExcel.cs b/src/Libraries/SmartStore.Data/Migrations/201403262015448_ImportExcel.cs index 3cf4f4c6b5..aa992d333a 100644 --- a/src/Libraries/SmartStore.Data/Migrations/201403262015448_ImportExcel.cs +++ b/src/Libraries/SmartStore.Data/Migrations/201403262015448_ImportExcel.cs @@ -44,7 +44,7 @@ public void MigrateLocaleResources(LocaleResourcesBuilder builder) "{0} von {1} Zeilen verarbeitet."); builder.AddOrUpdate("Admin.Common.ImportFromExcel.QuickStats", - "{0} new, {1} updated - with {2} warning(s) und {3} error(s).", + "{0} new, {1} updated - with {2} warning(s) and {3} error(s).", "{0} neu, {1} aktualisiert - bei {2} Warnung(en) und {3} Fehler(n)."); builder.AddOrUpdate("Admin.Common.ImportFromExcel.ActiveSince", diff --git a/src/Presentation/SmartStore.Web/App_Data/Localization/App/en/all.smres.xml b/src/Presentation/SmartStore.Web/App_Data/Localization/App/en/all.smres.xml index 1faea7a6fb..7881f9406c 100644 --- a/src/Presentation/SmartStore.Web/App_Data/Localization/App/en/all.smres.xml +++ b/src/Presentation/SmartStore.Web/App_Data/Localization/App/en/all.smres.xml @@ -3269,7 +3269,7 @@ {0} of {1} rows processed. - {0} new, {1} updated - with {2} warning(s) und {3} error(s). + {0} new, {1} updated - with {2} warning(s) and {3} error(s). Please wait while the import is being executed From 692d735d49fe27be283db3bf19f377bd9418be5c Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Wed, 23 Dec 2015 12:21:06 +0100 Subject: [PATCH 108/626] Validating and persisting import column mappings --- .../201512151526290_ImportFramework.cs | 7 +- .../ColumnMapping/ColumnMapConverter.cs | 4 +- .../Administration/Content/admin.less | 4 + .../Controllers/ImportController.cs | 126 ++++++++++-------- .../Models/DataExchange/ImportProfileModel.cs | 11 +- .../Views/Import/_ColumnMappings.cshtml | 27 ++-- .../Views/Import/_CreateOrUpdate.cshtml | 23 +++- 7 files changed, 127 insertions(+), 75 deletions(-) diff --git a/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs b/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs index a35e51d2e5..30dbca2b49 100644 --- a/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs +++ b/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs @@ -196,10 +196,15 @@ public void MigrateLocaleResources(LocaleResourcesBuilder builder) "Sie knnen optional fr jedes Feld der Importdatei festlegen, zu welcher Entittseigenschaft dessen Daten importiert werden sollen. Zudem ist die Angabe eines Standardwertes mglich, der angewendet wird, wenn das Importfeld leer ist."); builder.AddOrUpdate("Admin.DataExchange.ColumnMapping.ImportField", "Import Field", "Importfeld"); - builder.AddOrUpdate("Admin.DataExchange.ColumnMapping.ImportFieldIndex", "Index (language code etc.)", "Index (Sprach-Code etc.)"); + builder.AddOrUpdate("Admin.DataExchange.ColumnMapping.ImportFieldIndex", "Language Code etc.", "Sprach-Code etc."); builder.AddOrUpdate("Admin.DataExchange.ColumnMapping.EntityProperty", "Entity property", "Eigenschaft der Entitt"); builder.AddOrUpdate("Admin.DataExchange.ColumnMapping.DefaultValue", "Default Value", "Standard Wert"); + builder.AddOrUpdate("Admin.DataExchange.ColumnMapping.Validate.EntityMultipleMapped", + "The entity property \"{0}\" was assigned several times. Please assign each property only once.", + "Die Entittseigenschaft \"{0}\" wurde mehrfach zugeodnet. Bitte ordnen Sie jede Eigenschaft nur einmal zu."); + + builder.Delete( "Admin.DataExchange.Export.LastExecution", "Admin.DataExchange.Export.Offset", diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/ColumnMapping/ColumnMapConverter.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/ColumnMapping/ColumnMapConverter.cs index 12f251bd4d..7d6abcdc6d 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Import/ColumnMapping/ColumnMapConverter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/ColumnMapping/ColumnMapConverter.cs @@ -27,12 +27,12 @@ public override object ConvertFrom(CultureInfo culture, object value) { if (value is string) { - var dict = JsonConvert.DeserializeObject>((string)value); + var dict = JsonConvert.DeserializeObject>((string)value); var map = new ColumnMap(); foreach (var kvp in dict) { - map.AddMapping(kvp.Key, kvp.Value); + map.AddMapping(kvp.Key, kvp.Value.EntityProperty, kvp.Value.DefaultValue); } return map; diff --git a/src/Presentation/SmartStore.Web/Administration/Content/admin.less b/src/Presentation/SmartStore.Web/Administration/Content/admin.less index bef6c3f293..a27117a25a 100644 --- a/src/Presentation/SmartStore.Web/Administration/Content/admin.less +++ b/src/Presentation/SmartStore.Web/Administration/Content/admin.less @@ -891,6 +891,10 @@ tr.adminSeparator hr { select, input { margin-bottom: 0; } + .control-large { + width: 500px; + min-width: 500px; + } } /* SERVER CONTROLS */ diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs index fcf41629e3..33e1d7644c 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs @@ -45,63 +45,59 @@ public ImportController( #region Utilities - private List PrepareColumnMappingModels(ImportProfile profile, CsvConfiguration csvConfiguration) + private void PrepareColumnMappingModels(ImportProfile profile, ImportProfileModel model, CsvConfiguration csvConfiguration, ColumnMap invalidMap = null) { - var models = new List(); + model.ColumnMappings = new List(); + model.AvailableEntityProperties = new List(); try { var files = profile.GetImportFiles(); if (!files.Any()) - return models; + return; var filePath = files.First(); var mapConverter = new ColumnMapConverter(); - var map = mapConverter.ConvertFrom(profile.ColumnMapping); + + var map = (invalidMap != null ? invalidMap : mapConverter.ConvertFrom(profile.ColumnMapping)); var hasMappings = (map != null && map.Mappings.Any()); var destProperties = _importService.GetImportableEntityProperties(profile.EntityType); + model.AvailableEntityProperties = destProperties + .Select(x => new SelectListItem { Value = x.Key, Text = x.Value }) + .OrderBy(x => x.Text) + .ToList(); + using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) { + var index = 0; var dataTable = LightweightDataTable.FromFile(Path.GetFileName(filePath), stream, stream.Length, csvConfiguration, 0, 2); - foreach (var column in dataTable.Columns) + foreach (var column in dataTable.Columns.Where(x => x.Name.HasValue())) { - var sourceName = column.Name; - if (sourceName.IsEmpty()) - continue; - - var mapModel = new ColumnMappingItemModel(); + var mapModel = new ColumnMappingItemModel + { + Index = index++, + Column = column.Name + }; - var x1 = sourceName.IndexOf('['); - var x2 = sourceName.IndexOf(']'); + var x1 = column.Name.IndexOf('['); + var x2 = column.Name.IndexOf(']'); if (x1 != -1 && x2 != -1 && x2 > x1) { - mapModel.SourceColumn = sourceName.Substring(0, x1); - mapModel.SourceColumnIndex = sourceName.Substring(x1 + 1, x2 - x1 - 1); + mapModel.ColumnWithoutIndex = column.Name.Substring(0, x1); + mapModel.ColumnIndex = column.Name.Substring(x1 + 1, x2 - x1 - 1); } else { - mapModel.SourceColumn = sourceName; + mapModel.ColumnWithoutIndex = column.Name; } - mapModel.AvailableEntityProperties = destProperties - .Select(x => - { - return new SelectListItem - { - Value = "{0}¶{1}".FormatInvariant(sourceName, x.Key), - Text = (x.Key.IsCaseInsensitiveEqual(x.Value) ? x.Value : "{0} ({1})".FormatInvariant(x.Key, x.Value)), - Selected = (x.Key == sourceName) - }; - }) - .ToList(); - if (hasMappings) { - var mapping = map.Mappings.FirstOrDefault(x => x.Key == sourceName); + var mapping = map.Mappings.FirstOrDefault(x => x.Key == column.Name); if (mapping.Value != null) { mapModel.EntityProperty = mapping.Value.EntityProperty; @@ -109,7 +105,7 @@ private List PrepareColumnMappingModels(ImportProfile pr } } - models.Add(mapModel); + model.ColumnMappings.Add(mapModel); } } } @@ -117,10 +113,9 @@ private List PrepareColumnMappingModels(ImportProfile pr { NotifyError(exception); } - return models; } - private void PrepareProfileModel(ImportProfileModel model, ImportProfile profile, bool forEdit) + private void PrepareProfileModel(ImportProfileModel model, ImportProfile profile, bool forEdit, ColumnMap invalidMap = null) { if (forEdit) { @@ -161,7 +156,7 @@ private void PrepareProfileModel(ImportProfileModel model, ImportProfile profile model.CsvConfiguration = new CsvConfigurationModel(csvConfiguration); } - model.ColumnMappings = PrepareColumnMappingModels(profile, csvConfiguration ?? CsvConfiguration.ExcelFriendlyConfiguration); + PrepareColumnMappingModels(profile, model, csvConfiguration ?? CsvConfiguration.ExcelFriendlyConfiguration, invalidMap); } } else @@ -267,6 +262,42 @@ public ActionResult Edit(ImportProfileModel model, bool continueEditing, FormCol if (profile == null) return RedirectToAction("List"); + var map = new ColumnMap(); + var mapConverter = new ColumnMapConverter(); + var filePath = profile.GetImportFiles().First(); + + CsvConfiguration csvConfig = null; + if (model.CsvConfiguration != null) + { + csvConfig = model.CsvConfiguration.Clone(); + } + + using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) + { + var index = 0; + var dataTable = LightweightDataTable.FromFile(Path.GetFileName(filePath), stream, stream.Length, csvConfig ?? CsvConfiguration.ExcelFriendlyConfiguration, 0, 2); + + foreach (var column in dataTable.Columns.Where(x => x.Name.HasValue())) + { + var key = "ColumnMapping.EntityProperty." + index.ToString(); + if (form.AllKeys.Contains(key)) + { + var entityProperty = form[key]; + if (entityProperty.HasValue()) + { + if (map.Mappings.Any(x => x.Value.EntityProperty.IsCaseInsensitiveEqual(entityProperty))) + { + ModelState.AddModelError(key, T("Admin.DataExchange.ColumnMapping.Validate.EntityMultipleMapped", entityProperty)); + } + + var defaultValue = form["ColumnMapping.DefaultValue." + index.ToString()]; + map.AddMapping(column.Name, entityProperty, defaultValue); + } + } + ++index; + } + } + if (ModelState.IsValid) { profile.Name = model.Name; @@ -274,33 +305,14 @@ public ActionResult Edit(ImportProfileModel model, bool continueEditing, FormCol profile.Enabled = model.Enabled; profile.Skip = model.Skip; profile.Take = model.Take; + profile.FileTypeConfiguration = null; - if (model.ColumnMappings != null && model.ColumnMappings.Any()) - { - var map = new ColumnMap(); - var mapConverter = new ColumnMapConverter(); + profile.ColumnMapping = mapConverter.ConvertTo(map); - model.ColumnMappings.Each(x => map.AddMapping(x.SourceColumn, x.EntityProperty, x.DefaultValue)); - profile.ColumnMapping = mapConverter.ConvertTo(map); - } - else + if (profile.FileType == ImportFileType.CSV && csvConfig != null) { - profile.ColumnMapping = null; - } - - if (profile.FileType == ImportFileType.CSV) - { - if (model.CsvConfiguration != null) - { - CsvConfiguration config = model.CsvConfiguration.Clone(); - - var csvConverter = new CsvConfigurationConverter(); - profile.FileTypeConfiguration = csvConverter.ConvertTo(config); - } - else - { - profile.FileTypeConfiguration = null; - } + var csvConverter = new CsvConfigurationConverter(); + profile.FileTypeConfiguration = csvConverter.ConvertTo(csvConfig); } _importService.UpdateImportProfile(profile); @@ -310,7 +322,7 @@ public ActionResult Edit(ImportProfileModel model, bool continueEditing, FormCol return (continueEditing ? RedirectToAction("Edit", new { id = profile.Id }) : RedirectToAction("List")); } - PrepareProfileModel(model, profile, true); + PrepareProfileModel(model, profile, true, map); return View(model); } diff --git a/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ImportProfileModel.cs b/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ImportProfileModel.cs index e94418de1b..b45fd937c8 100644 --- a/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ImportProfileModel.cs +++ b/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ImportProfileModel.cs @@ -49,18 +49,17 @@ public partial class ImportProfileModel : EntityModelBase public CsvConfigurationModel CsvConfiguration { get; set; } public List ColumnMappings { get; set; } + public List AvailableEntityProperties { get; set; } } public class ColumnMappingItemModel { - public string SourceColumn { get; set; } - - public string SourceColumnIndex { get; set; } - + public int Index { get; set; } + public string Column { get; set; } + public string ColumnWithoutIndex { get; set; } + public string ColumnIndex { get; set; } public string EntityProperty { get; set; } - public List AvailableEntityProperties { get; set; } - public string DefaultValue { get; set; } } } \ No newline at end of file diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Import/_ColumnMappings.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Import/_ColumnMappings.cshtml index fb58dfb295..96dd2a534a 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Import/_ColumnMappings.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Import/_ColumnMappings.cshtml @@ -13,27 +13,38 @@ - - - + + + - @foreach (var mapping in Model.ColumnMappings.OrderBy(x => x.SourceColumn)) + @foreach (var mapping in Model.ColumnMappings.OrderBy(x => x.ColumnWithoutIndex)) { } diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Import/_CreateOrUpdate.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Import/_CreateOrUpdate.cshtml index fdd7767892..a9c0dddec5 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Import/_CreateOrUpdate.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Import/_CreateOrUpdate.cshtml @@ -177,7 +177,28 @@ return false; }); - $('#ImportColumnMappings').find('select').selectWrapper(); + $('#ImportColumnMappings').find('select').select2({ + allowClear: true, + minimumResultsForSearch: 16, + formatResult: columnMappingSelectItemFormatting, + formatSelection: columnMappingSelectItemFormatting + }); + + function columnMappingSelectItemFormatting(item) { + try { + var option = $(item.element); + + var html = '
' + item.text + ''; + if (option.length !== 0) { + html += ' (' + option.val() + ')'; + } + html += '
'; + + return html; + } + catch (e) { } + return item.text; + } }); \ No newline at end of file From 66c96dd15e64f64bd263eeeec016c8b3ee237688 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Wed, 23 Dec 2015 12:47:23 +0100 Subject: [PATCH 109/626] Button to reset all column mappings for an import profile --- .../201512151526290_ImportFramework.cs | 4 ++-- .../Controllers/ImportController.cs | 18 ++++++++++++++++++ .../Views/Import/_ColumnMappings.cshtml | 8 +++++++- .../Views/Import/_CreateOrUpdate.cshtml | 14 ++++++++++++++ 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs b/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs index 30dbca2b49..5caf8d7ec8 100644 --- a/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs +++ b/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs @@ -192,8 +192,8 @@ public void MigrateLocaleResources(LocaleResourcesBuilder builder) builder.AddOrUpdate("Admin.Promotions.NewsLetterSubscriptions.Fields.NewsLetterSubscriptionGuid", "Subscription GUID", "Abonnement GUID"); builder.AddOrUpdate("Admin.DataExchange.ColumnMapping.Note", - "For each field of the import file you can optionally set to which entity property whose data is to be imported. Specifying a default value is also possible, which is applied when the import field is empty.", - "Sie knnen optional fr jedes Feld der Importdatei festlegen, zu welcher Entittseigenschaft dessen Daten importiert werden sollen. Zudem ist die Angabe eines Standardwertes mglich, der angewendet wird, wenn das Importfeld leer ist."); + "For each field of the import file you can optionally set to which entity property whose data is to be imported. Specifying a default value is also possible, which is applied when the import field is empty. Through Reset all made assignments are reset to their original values.", + "Sie knnen optional fr jedes Feld der Importdatei festlegen, nach welcher Entittseigenschaft dessen Daten importiert werden sollen. Zudem ist die Angabe eines Standardwertes mglich, der angewendet wird, wenn das Importfeld leer ist. ber Zurcksetzen werden alle gettigten Zuordnungen auf ihre Ursprungswerte zurckgesetzt."); builder.AddOrUpdate("Admin.DataExchange.ColumnMapping.ImportField", "Import Field", "Importfeld"); builder.AddOrUpdate("Admin.DataExchange.ColumnMapping.ImportFieldIndex", "Language Code etc.", "Sprach-Code etc."); diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs index 33e1d7644c..9fecdbe9ea 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs @@ -327,6 +327,24 @@ public ActionResult Edit(ImportProfileModel model, bool continueEditing, FormCol return View(model); } + [HttpPost] + public ActionResult ResetColumnMappings(int id) + { + if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageImports)) + return AccessDeniedView(); + + var profile = _importService.GetImportProfileById(id); + if (profile == null) + return RedirectToAction("List"); + + profile.ColumnMapping = null; + _importService.UpdateImportProfile(profile); + + NotifySuccess(T("Admin.Common.TaskSuccessfullyProcessed")); + + return RedirectToAction("Edit", new { id = profile.Id }); + } + [HttpPost, ActionName("Delete")] public ActionResult DeleteConfirmed(int id) { diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Import/_ColumnMappings.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Import/_ColumnMappings.cshtml index 96dd2a534a..bc5bfd60b1 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Import/_ColumnMappings.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Import/_ColumnMappings.cshtml @@ -6,7 +6,13 @@
- @T("Admin.DataExchange.ColumnMapping.Note") + @Html.Raw(T("Admin.DataExchange.ColumnMapping.Note")) +
+ +
+
diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Import/_CreateOrUpdate.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Import/_CreateOrUpdate.cshtml index a9c0dddec5..bd24686006 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Import/_CreateOrUpdate.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Import/_CreateOrUpdate.cshtml @@ -177,6 +177,20 @@ return false; }); + // reset column mappings button + $('#ResetColumnMappings').click(function (e) { + e.preventDefault(); + + if (confirm('@T("Admin.Common.AskToProceed")')) { + var form = '
'; + $('body').append(form); + $('#ResetColumnMappingsForm').submit(); + } + + return false; + }); + + // init column mappings select $('#ImportColumnMappings').find('select').select2({ allowClear: true, minimumResultsForSearch: 16, From 4c90c15a64d832b9855271612cf3fb4afd3012e0 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Fri, 25 Dec 2015 11:03:25 +0100 Subject: [PATCH 110/626] Further implementation of import column mapping --- .../Localization/LocalizationHelper.cs | 22 ++- .../201512151526290_ImportFramework.cs | 9 +- .../Catalog/Importer/CategoryImporter.cs | 14 +- .../Catalog/Importer/ProductImporter.cs | 24 ++-- .../Customers/Importer/CustomerImporter.cs | 8 +- .../Import/ColumnMapping/ColumnMap.cs | 76 +++++++--- .../ColumnMapping/ColumnMapConverter.cs | 2 +- .../DataExchange/Import/DataImporter.cs | 5 + .../Import/DataTable/LightweightDataTable.cs | 14 +- .../DataExchange/Import/IEntityImporter.cs | 77 +---------- .../Import/ImportDataSegmenter.cs | 5 +- .../Import/ImportExecuteContext.cs | 130 ++++++++++++++++++ .../DataExchange/Import/ImportRow.cs | 78 ++++++----- .../NewsLetterSubscriptionImporter.cs | 5 +- .../SmartStore.Services.csproj | 1 + .../Controllers/ImportController.cs | 78 +++++++---- .../Models/DataExchange/ImportProfileModel.cs | 11 +- .../Views/Import/_ColumnMappings.cshtml | 37 +++-- .../Views/Import/_CreateOrUpdate.cshtml | 16 ++- .../Controllers/CommonController.cs | 25 +--- .../DataExchange/ImportDataSegmenterTests.cs | 8 +- 21 files changed, 403 insertions(+), 242 deletions(-) create mode 100644 src/Libraries/SmartStore.Services/DataExchange/Import/ImportExecuteContext.cs diff --git a/src/Libraries/SmartStore.Core/Localization/LocalizationHelper.cs b/src/Libraries/SmartStore.Core/Localization/LocalizationHelper.cs index d4c940ee36..118128c58e 100644 --- a/src/Libraries/SmartStore.Core/Localization/LocalizationHelper.cs +++ b/src/Libraries/SmartStore.Core/Localization/LocalizationHelper.cs @@ -1,11 +1,10 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Globalization; using System.Linq; namespace SmartStore.Core.Localization { - public static class LocalizationHelper + public static class LocalizationHelper { private readonly static HashSet _cultureCodes = new HashSet( @@ -18,5 +17,20 @@ public static bool IsValidCultureCode(string cultureCode) return _cultureCodes.Contains(cultureCode); } - } + public static string GetLanguageNativeName(string locale) + { + try + { + if (locale.HasValue()) + { + var info = CultureInfo.GetCultureInfoByIetfLanguageTag(locale); + if (info != null) + return info.NativeName; + } + } + catch { } + + return null; + } + } } diff --git a/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs b/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs index 5caf8d7ec8..d54bff9b5c 100644 --- a/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs +++ b/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs @@ -65,6 +65,8 @@ public void MigrateLocaleResources(LocaleResourcesBuilder builder) "Specifies the number of records to be skipped.", "Legt die Anzahl der zu berspringenden Datenstze fest."); + builder.AddOrUpdate("Common.Unknown", "Unknown", "Unbekannt"); + builder.AddOrUpdate("Common.Language", "Language", "Sprache"); builder.AddOrUpdate("Admin.Common.ImportFile", "Import file", "Importdatei"); builder.AddOrUpdate("Admin.Common.ImportFiles", "Import files", "Importdateien"); builder.AddOrUpdate("Admin.Common.CsvConfiguration", "CSV Configuration", "CSV Konfiguration"); @@ -192,13 +194,12 @@ public void MigrateLocaleResources(LocaleResourcesBuilder builder) builder.AddOrUpdate("Admin.Promotions.NewsLetterSubscriptions.Fields.NewsLetterSubscriptionGuid", "Subscription GUID", "Abonnement GUID"); builder.AddOrUpdate("Admin.DataExchange.ColumnMapping.Note", - "For each field of the import file you can optionally set to which entity property whose data is to be imported. Specifying a default value is also possible, which is applied when the import field is empty. Through Reset all made assignments are reset to their original values.", - "Sie knnen optional fr jedes Feld der Importdatei festlegen, nach welcher Entittseigenschaft dessen Daten importiert werden sollen. Zudem ist die Angabe eines Standardwertes mglich, der angewendet wird, wenn das Importfeld leer ist. ber Zurcksetzen werden alle gettigten Zuordnungen auf ihre Ursprungswerte zurckgesetzt."); + "For each field of the import file you can optionally set whether and to which entity property the data is to be imported. Specifying a default value is also possible, which is applied when the import field is empty. Through Reset all made assignments are reset to their original values.", + "Sie knnen optional fr jedes Feld der Importdatei festlegen, ob und nach welcher Entittseigenschaft dessen Daten importiert werden sollen. Zudem ist die Angabe eines Standardwertes mglich, der angewendet wird, wenn das Importfeld leer ist. ber Zurcksetzen werden alle gettigten Zuordnungen auf ihre Ursprungswerte zurckgesetzt."); builder.AddOrUpdate("Admin.DataExchange.ColumnMapping.ImportField", "Import Field", "Importfeld"); - builder.AddOrUpdate("Admin.DataExchange.ColumnMapping.ImportFieldIndex", "Language Code etc.", "Sprach-Code etc."); builder.AddOrUpdate("Admin.DataExchange.ColumnMapping.EntityProperty", "Entity property", "Eigenschaft der Entitt"); - builder.AddOrUpdate("Admin.DataExchange.ColumnMapping.DefaultValue", "Default Value", "Standard Wert"); + builder.AddOrUpdate("Admin.DataExchange.ColumnMapping.DefaultValue", "Default Value", "Standardwert"); builder.AddOrUpdate("Admin.DataExchange.ColumnMapping.Validate.EntityMultipleMapped", "The entity property \"{0}\" was assigned several times. Please assign each property only once.", diff --git a/src/Libraries/SmartStore.Services/Catalog/Importer/CategoryImporter.cs b/src/Libraries/SmartStore.Services/Catalog/Importer/CategoryImporter.cs index 233a36e638..50ffb37a4e 100644 --- a/src/Libraries/SmartStore.Services/Catalog/Importer/CategoryImporter.cs +++ b/src/Libraries/SmartStore.Services/Catalog/Importer/CategoryImporter.cs @@ -49,7 +49,7 @@ public CategoryImporter( _seoSettings = seoSettings; } - private int ProcessSlugs(ImportExecuteContext context, ImportRow[] batch) + private int ProcessSlugs(IImportExecuteContext context, ImportRow[] batch) { var slugMap = new Dictionary(100); Func slugLookup = ((s) => @@ -109,7 +109,7 @@ private int ProcessSlugs(ImportExecuteContext context, ImportRow[] bat return _urlRecordRepository.Context.SaveChanges(); } - private int ProcessParentMappings(ImportExecuteContext context, + private int ProcessParentMappings(IImportExecuteContext context, ImportRow[] batch, Dictionary oldToNewId) { @@ -143,7 +143,7 @@ private int ProcessParentMappings(ImportExecuteContext context, return num; } - private int ProcessCategories(ImportExecuteContext context, + private int ProcessCategories(IImportExecuteContext context, ImportRow[] batch, DateTime utcNow, List allCategoryTemplateIds, @@ -292,8 +292,9 @@ private int ProcessCategories(ImportExecuteContext context, return num; } - public void Execute(ImportExecuteContext context) + public void Execute(IImportExecuteContext context) { + var utcNow = DateTime.UtcNow; var oldToNewId = new Dictionary(); var allCategoryTemplateIds = _categoryTemplateService.GetAllCategoryTemplates() @@ -302,8 +303,7 @@ public void Execute(ImportExecuteContext context) using (var scope = new DbContextScope(ctx: _categoryRepository.Context, autoDetectChanges: false, proxyCreation: false, validateOnSave: false)) { - var segmenter = new ImportDataSegmenter(context.DataTable); - var utcNow = DateTime.UtcNow; + var segmenter = context.GetSegmenter(); context.Result.TotalRecords = segmenter.TotalRows; @@ -333,7 +333,7 @@ public void Execute(ImportExecuteContext context) context.Result.NewRecords += batch.Count(x => x.IsNew && !x.IsTransient); context.Result.ModifiedRecords += batch.Count(x => !x.IsNew && !x.IsTransient); - if (context.DataTable.HasColumn("SeName") || batch.Any(x => x.IsNew || x.NameChanged)) + if (context.HasColumn("SeName") || batch.Any(x => x.IsNew || x.NameChanged)) { try { diff --git a/src/Libraries/SmartStore.Services/Catalog/Importer/ProductImporter.cs b/src/Libraries/SmartStore.Services/Catalog/Importer/ProductImporter.cs index 231872f859..dba41684e4 100644 --- a/src/Libraries/SmartStore.Services/Catalog/Importer/ProductImporter.cs +++ b/src/Libraries/SmartStore.Services/Catalog/Importer/ProductImporter.cs @@ -80,7 +80,7 @@ public ProductImporter( return (int?)null; } - private void ProcessProductPictures(ImportExecuteContext context, ImportRow[] batch) + private void ProcessProductPictures(IImportExecuteContext context, ImportRow[] batch) { // true, cause pictures must be saved and assigned an id prior adding a mapping. _productPictureRepository.AutoCommitEnabled = true; @@ -151,7 +151,7 @@ private void ProcessProductPictures(ImportExecuteContext context, ImportRow[] batch) + private int ProcessProductManufacturers(IImportExecuteContext context, ImportRow[] batch) { _productManufacturerRepository.AutoCommitEnabled = false; @@ -202,7 +202,7 @@ private int ProcessProductManufacturers(ImportExecuteContext context, ImportRow< return num; } - private int ProcessProductCategories(ImportExecuteContext context, ImportRow[] batch) + private int ProcessProductCategories(IImportExecuteContext context, ImportRow[] batch) { _productCategoryRepository.AutoCommitEnabled = false; @@ -253,7 +253,7 @@ private int ProcessProductCategories(ImportExecuteContext context, ImportRow[] batch) + private int ProcessLocalizations(IImportExecuteContext context, ImportRow[] batch) { //_rsProductManufacturer.AutoCommitEnabled = false; @@ -307,7 +307,7 @@ private int ProcessLocalizations(ImportExecuteContext context, ImportRow[] batch) + private int ProcessSlugs(IImportExecuteContext context, ImportRow[] batch) { var slugMap = new Dictionary(100); Func slugLookup = ((s) => @@ -367,7 +367,7 @@ private int ProcessSlugs(ImportExecuteContext context, ImportRow[] batc return _urlRecordRepository.Context.SaveChanges(); } - private int ProcessProducts(ImportExecuteContext context, ImportRow[] batch, DateTime utcNow) + private int ProcessProducts(IImportExecuteContext context, ImportRow[] batch, DateTime utcNow) { _productRepository.AutoCommitEnabled = true; @@ -538,11 +538,11 @@ private int ProcessProducts(ImportExecuteContext context, ImportRow[] b return num; } - public void Execute(ImportExecuteContext context) + public void Execute(IImportExecuteContext context) { using (var scope = new DbContextScope(ctx: _productRepository.Context, autoDetectChanges: false, proxyCreation: false, validateOnSave: false)) { - var segmenter = new ImportDataSegmenter(context.DataTable); + var segmenter = context.GetSegmenter(); var utcNow = DateTime.UtcNow; context.Result.TotalRecords = segmenter.TotalRows; @@ -581,7 +581,7 @@ public void Execute(ImportExecuteContext context) // IMPORTANT: Unlike with Products AutoCommitEnabled must be TRUE, // as Slugs are going to be validated against existing ones in DB. // =========================================================================== - if (context.DataTable.HasColumn("SeName") || batch.Any(x => x.IsNew || x.NameChanged)) + if (context.HasColumn("SeName") || batch.Any(x => x.IsNew || x.NameChanged)) { try { @@ -613,7 +613,7 @@ public void Execute(ImportExecuteContext context) // =========================================================================== // 4.) Import product category mappings // =========================================================================== - if (context.DataTable.HasColumn("CategoryIds")) + if (context.HasColumn("CategoryIds")) { try { @@ -628,7 +628,7 @@ public void Execute(ImportExecuteContext context) // =========================================================================== // 5.) Import product manufacturer mappings // =========================================================================== - if (context.DataTable.HasColumn("ManufacturerIds")) + if (context.HasColumn("ManufacturerIds")) { try { @@ -643,7 +643,7 @@ public void Execute(ImportExecuteContext context) // =========================================================================== // 6.) Import product picture mappings // =========================================================================== - if (context.DataTable.HasColumn("PictureThumbPaths")) + if (context.HasColumn("PictureThumbPaths")) { try { diff --git a/src/Libraries/SmartStore.Services/Customers/Importer/CustomerImporter.cs b/src/Libraries/SmartStore.Services/Customers/Importer/CustomerImporter.cs index 4236fa81f8..e486a5c7f0 100644 --- a/src/Libraries/SmartStore.Services/Customers/Importer/CustomerImporter.cs +++ b/src/Libraries/SmartStore.Services/Customers/Importer/CustomerImporter.cs @@ -72,7 +72,7 @@ private void UpsertRole(ImportRow row, CustomerRole role, string roleS } } - private int ProcessGenericAttributes(ImportExecuteContext context, + private int ProcessGenericAttributes(IImportExecuteContext context, ImportRow[] batch, List allCountryIds, List allStateProvinceIds, @@ -162,7 +162,7 @@ private int ProcessGenericAttributes(ImportExecuteContext context, return num; } - private int ProcessCustomers(ImportExecuteContext context, + private int ProcessCustomers(IImportExecuteContext context, ImportRow[] batch, DateTime utcNow, List allAffiliateIds, @@ -270,7 +270,7 @@ private int ProcessCustomers(ImportExecuteContext context, return num; } - public void Execute(ImportExecuteContext context) + public void Execute(IImportExecuteContext context) { var utcNow = DateTime.UtcNow; var customer = _customerService.GetCustomerById(context.CustomerId); @@ -296,7 +296,7 @@ public void Execute(ImportExecuteContext context) using (var scope = new DbContextScope(ctx: _services.DbContext, autoDetectChanges: false, proxyCreation: false, validateOnSave: false, autoCommit: false)) { - var segmenter = new ImportDataSegmenter(context.DataTable); + var segmenter = context.GetSegmenter(); context.Result.TotalRecords = segmenter.TotalRows; diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/ColumnMapping/ColumnMap.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/ColumnMapping/ColumnMap.cs index b7f588d487..df66ad1e56 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Import/ColumnMapping/ColumnMap.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/ColumnMapping/ColumnMap.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; namespace SmartStore.Services.DataExchange.Import { @@ -7,11 +8,63 @@ public class ColumnMap { private readonly Dictionary _map = new Dictionary(StringComparer.OrdinalIgnoreCase); + private static bool IsIndexed(string name) + { + return (name.EmptyNull().EndsWith("]") && name.EmptyNull().Contains("[")); + } + + private static string CreateSourceName(string name, string index) + { + if (index.HasValue()) + { + name += String.Concat("[", index, "]"); + } + + return name; + } + public IReadOnlyDictionary Mappings { get { return _map; } } + public static bool ParseSourceColumn(string sourceColumn, out string columnWithoutIndex, out string index) + { + columnWithoutIndex = sourceColumn; + index = null; + + var result = true; + + if (sourceColumn.HasValue() && IsIndexed(sourceColumn)) + { + var x1 = sourceColumn.IndexOf('['); + var x2 = sourceColumn.IndexOf(']', x1); + + if (x1 != -1 && x2 != -1 && x2 > x1) + { + columnWithoutIndex = sourceColumn.Substring(0, x1); + index = sourceColumn.Substring(x1 + 1, x2 - x1 - 1); + } + else + { + result = false; + } + } + + return result; + } + + public IEnumerable> GetInvalidMappings() + { + var mappings = Mappings.Where(x => + !IsIndexed(x.Key) && + x.Value.Property.HasValue() && + Mappings.Count(y => y.Value.Property.IsCaseInsensitiveEqual(x.Value.Property)) > 1 + ); + + return mappings; + } + public void AddMapping(string sourceColumn, string entityProperty, string defaultValue = null) { AddMapping(sourceColumn, null, entityProperty, defaultValue); @@ -20,12 +73,11 @@ public void AddMapping(string sourceColumn, string entityProperty, string defaul public void AddMapping(string sourceColumn, string index, string entityProperty, string defaultValue = null) { Guard.ArgumentNotEmpty(() => sourceColumn); - Guard.ArgumentNotEmpty(() => entityProperty); _map[CreateSourceName(sourceColumn, index)] = new ColumnMappingValue { - EntityProperty = entityProperty, - DefaultValue = defaultValue + Property = entityProperty, + Default = defaultValue }; } @@ -43,7 +95,7 @@ public ColumnMappingValue GetMapping(string sourceColumn) return result; } - return new ColumnMappingValue { EntityProperty = sourceColumn }; + return new ColumnMappingValue { Property = sourceColumn }; } /// @@ -68,7 +120,7 @@ public string GetMappedProperty(string sourceColumn) if (_map.TryGetValue(sourceColumn, out result)) { - return result.EntityProperty; + return result.Property; } return sourceColumn; @@ -84,16 +136,6 @@ public string GetMappedProperty(string sourceColumn, string index) { return GetMappedProperty(CreateSourceName(sourceColumn, index)); } - - internal static string CreateSourceName(string name, string index) - { - if (index.HasValue()) - { - name += String.Concat("[", index, "]"); - } - - return name; - } } @@ -102,11 +144,11 @@ public class ColumnMappingValue /// /// The property name of the target entity /// - public string EntityProperty { get; set; } + public string Property { get; set; } /// /// An optional default value /// - public string DefaultValue { get; set; } + public string Default { get; set; } } } diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/ColumnMapping/ColumnMapConverter.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/ColumnMapping/ColumnMapConverter.cs index 7d6abcdc6d..78cbd7fa13 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Import/ColumnMapping/ColumnMapConverter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/ColumnMapping/ColumnMapConverter.cs @@ -32,7 +32,7 @@ public override object ConvertFrom(CultureInfo culture, object value) foreach (var kvp in dict) { - map.AddMapping(kvp.Key, kvp.Value.EntityProperty, kvp.Value.DefaultValue); + map.AddMapping(kvp.Key, null, kvp.Value.Property, kvp.Value.Default); } return map; diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/DataImporter.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/DataImporter.cs index b455823401..55ab3376fb 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Import/DataImporter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/DataImporter.cs @@ -270,6 +270,11 @@ private void ImportCoreOuter(DataImporterContext ctx) ctx.ExecuteContext.CustomerId = ctx.Request.CustomerId; + { + var mapConverter = new ColumnMapConverter(); + ctx.ExecuteContext.ColumnMap = mapConverter.ConvertFrom(ctx.Request.Profile.ColumnMapping) ?? new ColumnMap(); + } + var files = ctx.Request.Profile.GetImportFiles(); if (files.Count == 0) diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/DataTable/LightweightDataTable.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/DataTable/LightweightDataTable.cs index d8ca9b8e8c..99d3f4db48 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Import/DataTable/LightweightDataTable.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/DataTable/LightweightDataTable.cs @@ -42,20 +42,20 @@ public LightweightDataTable(IList columns, IList data) public bool HasColumn(string name) { + if (name.IsEmpty()) + return false; + return _columnIndexes.ContainsKey(name); } public int GetColumnIndex(string name) { - Guard.ArgumentNotEmpty(name, "name"); - int index; - if (!_columnIndexes.TryGetValue(name, out index)) - { - return -1; - } - return index; + if (name.HasValue() && _columnIndexes.TryGetValue(name, out index)) + return index; + + return -1; } public IList Columns diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/IEntityImporter.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/IEntityImporter.cs index 1772fce95e..a33f2a3ccd 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Import/IEntityImporter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/IEntityImporter.cs @@ -1,78 +1,7 @@ -using System.Linq; -using System.Collections.Generic; -using System.Threading; -using SmartStore.Core.Domain.DataExchange; - -namespace SmartStore.Services.DataExchange.Import +namespace SmartStore.Services.DataExchange.Import { - public interface IEntityImporter + public partial interface IEntityImporter { - void Execute(ImportExecuteContext context); - } - - - public class ImportExecuteContext - { - private DataExchangeAbortion _abortion; - private CancellationToken _cancellation; - private ProgressValueSetter _progressValueSetter; - private string _progressInfo; - - public ImportExecuteContext( - CancellationToken cancellation, - ProgressValueSetter progressValueSetter, - string progressInfo) - { - _cancellation = cancellation; - _progressValueSetter = progressValueSetter; - _progressInfo = progressInfo; - - CustomProperties = new Dictionary(); - Result = new ImportResult(); - } - - public IDataTable DataTable { get; internal set; } - - public int CustomerId { get; internal set; } - - /// - /// Use this dictionary for any custom data required along the import - /// - public Dictionary CustomProperties { get; private set; } - - public ImportResult Result { get; set; } - - public DataExchangeAbortion Abort - { - get - { - if (_cancellation.IsCancellationRequested || IsMaxFailures) - return DataExchangeAbortion.Hard; - - return _abortion; - } - set - { - _abortion = value; - } - } - - public bool IsMaxFailures - { - get - { - return Result.Messages.Count(x => x.MessageType == ImportMessageType.Error) > 11; - } - } - - public void SetProgress(int value, int maximum) - { - try - { - if (_progressValueSetter != null) - _progressValueSetter.Invoke(value, maximum, _progressInfo.FormatInvariant(value, maximum)); - } - catch { } - } + void Execute(IImportExecuteContext context); } } diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportDataSegmenter.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportDataSegmenter.cs index d9ecad1d7b..991398d73f 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportDataSegmenter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportDataSegmenter.cs @@ -21,16 +21,17 @@ public class ImportDataSegmenter where T : BaseEntity private readonly IDictionary _columnIndexes = new Dictionary(StringComparer.OrdinalIgnoreCase); - public ImportDataSegmenter(IDataTable table) + public ImportDataSegmenter(IDataTable table, ColumnMap map) { Guard.ArgumentNotNull(() => table); + Guard.ArgumentNotNull(() => map); _table = table; + _columnMap = map; _bof = true; _pageable = new PagedList(0, BATCHSIZE, table.Rows.Count); _culture = CultureInfo.InvariantCulture; - _columnMap = new ColumnMap(); } public CultureInfo Culture diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportExecuteContext.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportExecuteContext.cs new file mode 100644 index 0000000000..3a0ebe03a2 --- /dev/null +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportExecuteContext.cs @@ -0,0 +1,130 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using SmartStore.Core; +using SmartStore.Core.Domain.DataExchange; + +namespace SmartStore.Services.DataExchange.Import +{ + public interface IImportExecuteContext + { + /// + /// Context customer identifier + /// + int CustomerId { get; } + + /// + /// Use this dictionary for any custom data required along the export + /// + Dictionary CustomProperties { get; set; } + + /// + /// Result of the import + /// + ImportResult Result { get; set; } + + /// + /// Indicates whether and how to abort the import + /// + DataExchangeAbortion Abort { get; set; } + + /// + /// Creates a segmenter instance + /// + /// + /// + ImportDataSegmenter GetSegmenter() where TEntity : BaseEntity; + + /// + /// Whether the data source contains a particular column + /// + /// + /// + bool HasColumn(string name); + + /// + /// Allows to set a progress message + /// + /// Progress value + /// /// Progress maximum + void SetProgress(int value, int maximum); + } + + + public class ImportExecuteContext : IImportExecuteContext + { + private DataExchangeAbortion _abortion; + private CancellationToken _cancellation; + private ProgressValueSetter _progressValueSetter; + private string _progressInfo; + + public ImportExecuteContext( + CancellationToken cancellation, + ProgressValueSetter progressValueSetter, + string progressInfo) + { + _cancellation = cancellation; + _progressValueSetter = progressValueSetter; + _progressInfo = progressInfo; + + CustomProperties = new Dictionary(); + Result = new ImportResult(); + } + + public IDataTable DataTable { get; internal set; } + + public ColumnMap ColumnMap { get; internal set; } + + public int CustomerId { get; internal set; } + + /// + /// Use this dictionary for any custom data required along the import + /// + public Dictionary CustomProperties { get; set; } + + public ImportResult Result { get; set; } + + public DataExchangeAbortion Abort + { + get + { + if (_cancellation.IsCancellationRequested || IsMaxFailures) + return DataExchangeAbortion.Hard; + + return _abortion; + } + set + { + _abortion = value; + } + } + + public bool IsMaxFailures + { + get + { + return Result.Messages.Count(x => x.MessageType == ImportMessageType.Error) > 11; + } + } + + public ImportDataSegmenter GetSegmenter() where TEntity : BaseEntity + { + return new ImportDataSegmenter(DataTable, ColumnMap); + } + + public bool HasColumn(string name) + { + return DataTable.HasColumn(name); + } + + public void SetProgress(int value, int maximum) + { + try + { + if (_progressValueSetter != null) + _progressValueSetter.Invoke(value, maximum, _progressInfo.FormatInvariant(value, maximum)); + } + catch { } + } + } +} diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportRow.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportRow.cs index da18417c95..662d4c32b5 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportRow.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportRow.cs @@ -18,6 +18,27 @@ public class ImportRow where T : BaseEntity private readonly ImportDataSegmenter _segmenter; private readonly IDataRow _row; + private TProp GetDefaultValue(ColumnMappingValue mapping, string columnName, TProp defaultValue, ImportResult result = null) + { + if (mapping != null && mapping.Default.HasValue()) + { + try + { + return mapping.Default.Convert(_segmenter.Culture); + } + catch (Exception exception) + { + if (result != null) + { + var msg = "Failed to convert default value '{0}'. Please specify a convertable default value. {1}"; + result.AddWarning(msg.FormatInvariant(mapping.Default, exception.Message), this.GetRowInfo(), columnName); + } + } + } + + return defaultValue; + } + public ImportRow(ImportDataSegmenter parent, IDataRow row, int position) { _segmenter = parent; @@ -91,12 +112,14 @@ public TProp GetDataValue(string columnName) public TProp GetDataValue(string columnName, string index) { object value; - if (_row.TryGetValue(_segmenter.ColumnMap.GetMappedProperty(columnName, index), out value)) + var mapping = _segmenter.ColumnMap.GetMapping(columnName, index); + + if (_row.TryGetValue(mapping.Property, out value) && value != DBNull.Value) { return value.Convert(_segmenter.Culture); } - return default(TProp); + return GetDefaultValue(mapping, columnName, default(TProp)); } public bool SetProperty( @@ -109,33 +132,16 @@ public bool SetProperty( // TBD: (MC) do not check for perf reason? //CheckInitialized(); + var isPropertySet = false; var pi = prop.ExtractPropertyInfo(); var propName = pi.Name; try { - var fastProp = FastProperty.GetProperty(target.GetUnproxiedType(), propName, PropertyCachingStrategy.EagerCached); - object value; var mapping = _segmenter.ColumnMap.GetMapping(propName); - if (mapping.DefaultValue != null) - { - try - { - if (mapping.DefaultValue.IsEmpty()) - defaultValue = default(TProp); // ignore called in value and explicitly convert to default - else - defaultValue = mapping.DefaultValue.Convert(_segmenter.Culture); - } - catch (Exception exception) - { - var msg = "Failed to convert default value '{0}'. Please specify a convertable default value. {1}"; - result.AddWarning(msg.FormatInvariant(mapping.DefaultValue.NaIfEmpty(), exception.Message), this.GetRowInfo(), propName); - } - } - - if (_row.TryGetValue(mapping.EntityProperty, out value)) + if (_row.TryGetValue(mapping.Property, out value)) { // source contains field value. Set it. TProp converted; @@ -143,25 +149,33 @@ public bool SetProperty( { converted = converter(value, _segmenter.Culture); } + else if (value == DBNull.Value || value.ToString().IsCaseInsensitiveEqual("NULL")) + { + converted = GetDefaultValue(mapping, propName, defaultValue, result); + } else { - converted = value.ToString().ToUpper().Equals("NULL") - ? default(TProp) - : value.Convert(_segmenter.Culture); + converted = value.Convert(_segmenter.Culture); } + var fastProp = FastProperty.GetProperty(target.GetUnproxiedType(), propName, PropertyCachingStrategy.EagerCached); fastProp.SetValue(target, converted); - return true; + isPropertySet = true; } else { - // source does not contain field data or is empty... - if (IsTransient && defaultValue != null) + if (IsTransient) { - // ...but the entity is new. In this case - // set the default value if given. - fastProp.SetValue(target, defaultValue); - return true; + defaultValue = GetDefaultValue(mapping, propName, defaultValue, result); + + // source does not contain field data or is empty... + if (defaultValue != null) + { + // ...but the entity is new. In this case set the default value if given. + var fastProp = FastProperty.GetProperty(target.GetUnproxiedType(), propName, PropertyCachingStrategy.EagerCached); + fastProp.SetValue(target, defaultValue); + isPropertySet = true; + } } } } @@ -170,7 +184,7 @@ public bool SetProperty( result.AddWarning("Conversion failed: " + exception.Message, this.GetRowInfo(), propName); } - return false; + return isPropertySet; } public ImportRowInfo GetRowInfo() diff --git a/src/Libraries/SmartStore.Services/Messages/Importer/NewsLetterSubscriptionImporter.cs b/src/Libraries/SmartStore.Services/Messages/Importer/NewsLetterSubscriptionImporter.cs index 0037b755f4..5bf83c4755 100644 --- a/src/Libraries/SmartStore.Services/Messages/Importer/NewsLetterSubscriptionImporter.cs +++ b/src/Libraries/SmartStore.Services/Messages/Importer/NewsLetterSubscriptionImporter.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Globalization; using System.Linq; using SmartStore.Core.Data; using SmartStore.Core.Domain.DataExchange; @@ -22,7 +21,7 @@ public NewsLetterSubscriptionImporter( _subscriptionRepository = subscriptionRepository; } - public void Execute(ImportExecuteContext context) + public void Execute(IImportExecuteContext context) { var utcNow = DateTime.UtcNow; var currentStoreId = _services.StoreContext.CurrentStore.Id; @@ -32,7 +31,7 @@ public void Execute(ImportExecuteContext context) using (var scope = new DbContextScope(ctx: _services.DbContext, autoDetectChanges: false, proxyCreation: false, validateOnSave: false, autoCommit: false)) { - var segmenter = new ImportDataSegmenter(context.DataTable); + var segmenter = context.GetSegmenter(); context.Result.TotalRecords = segmenter.TotalRows; diff --git a/src/Libraries/SmartStore.Services/SmartStore.Services.csproj b/src/Libraries/SmartStore.Services/SmartStore.Services.csproj index 405df35f5a..344a61ef2a 100644 --- a/src/Libraries/SmartStore.Services/SmartStore.Services.csproj +++ b/src/Libraries/SmartStore.Services/SmartStore.Services.csproj @@ -190,6 +190,7 @@ + diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs index 9fecdbe9ea..11418e16e9 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Linq; using System.Web.Mvc; @@ -8,6 +9,7 @@ using SmartStore.Core.Domain; using SmartStore.Core.Domain.DataExchange; using SmartStore.Core.IO; +using SmartStore.Core.Localization; using SmartStore.Services; using SmartStore.Services.DataExchange.Csv; using SmartStore.Services.DataExchange.Import; @@ -30,17 +32,20 @@ public class ImportController : AdminControllerBase private readonly IImportProfileService _importService; private readonly IDateTimeHelper _dateTimeHelper; private readonly ITaskScheduler _taskScheduler; + private readonly ILanguageService _languageService; public ImportController( ICommonServices services, IImportProfileService importService, IDateTimeHelper dateTimeHelper, - ITaskScheduler taskScheduler) + ITaskScheduler taskScheduler, + ILanguageService languageService) { _services = services; _importService = importService; _dateTimeHelper = dateTimeHelper; _taskScheduler = taskScheduler; + _languageService = languageService; } #region Utilities @@ -58,6 +63,7 @@ private void PrepareColumnMappingModels(ImportProfile profile, ImportProfileMode var filePath = files.First(); var mapConverter = new ColumnMapConverter(); + var allLanguages = _languageService.GetAllLanguages(true); var map = (invalidMap != null ? invalidMap : mapConverter.ConvertFrom(profile.ColumnMapping)); var hasMappings = (map != null && map.Mappings.Any()); @@ -71,28 +77,35 @@ private void PrepareColumnMappingModels(ImportProfile profile, ImportProfileMode using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) { - var index = 0; - var dataTable = LightweightDataTable.FromFile(Path.GetFileName(filePath), stream, stream.Length, csvConfiguration, 0, 2); + var dataTable = LightweightDataTable.FromFile(Path.GetFileName(filePath), stream, stream.Length, csvConfiguration, 0, 1); foreach (var column in dataTable.Columns.Where(x => x.Name.HasValue())) { + string columnWithoutIndex; + string columnIndex; + ColumnMap.ParseSourceColumn(column.Name, out columnWithoutIndex, out columnIndex); + var mapModel = new ColumnMappingItemModel { - Index = index++, - Column = column.Name + Index = dataTable.Columns.IndexOf(column), + Column = column.Name, + ColumnWithoutIndex = columnWithoutIndex, + ColumnIndex = columnIndex }; - var x1 = column.Name.IndexOf('['); - var x2 = column.Name.IndexOf(']'); - - if (x1 != -1 && x2 != -1 && x2 > x1) + if (destProperties.ContainsKey(column.Name)) { - mapModel.ColumnWithoutIndex = column.Name.Substring(0, x1); - mapModel.ColumnIndex = column.Name.Substring(x1 + 1, x2 - x1 - 1); + mapModel.ColumnLocalized = destProperties[column.Name]; } - else + + if (columnIndex.HasValue()) { - mapModel.ColumnWithoutIndex = column.Name; + var language = allLanguages.FirstOrDefault(x => x.UniqueSeoCode.IsCaseInsensitiveEqual(columnIndex)); + if (language != null) + { + mapModel.LanguageDescription = LocalizationHelper.GetLanguageNativeName(language.LanguageCulture); + mapModel.FlagImageFileName = language.FlagImageFileName; + } } if (hasMappings) @@ -100,8 +113,9 @@ private void PrepareColumnMappingModels(ImportProfile profile, ImportProfileMode var mapping = map.Mappings.FirstOrDefault(x => x.Key == column.Name); if (mapping.Value != null) { - mapModel.EntityProperty = mapping.Value.EntityProperty; - mapModel.DefaultValue = mapping.Value.DefaultValue; + mapModel.Property = mapping.Value.Property; + mapModel.Default = mapping.Value.Default; + mapModel.IsNilProperty = mapping.Value.Property.IsEmpty(); } } @@ -274,27 +288,35 @@ public ActionResult Edit(ImportProfileModel model, bool continueEditing, FormCol using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) { - var index = 0; - var dataTable = LightweightDataTable.FromFile(Path.GetFileName(filePath), stream, stream.Length, csvConfig ?? CsvConfiguration.ExcelFriendlyConfiguration, 0, 2); + var dataTable = LightweightDataTable.FromFile(Path.GetFileName(filePath), stream, stream.Length, csvConfig ?? CsvConfiguration.ExcelFriendlyConfiguration, 0, 1); foreach (var column in dataTable.Columns.Where(x => x.Name.HasValue())) { - var key = "ColumnMapping.EntityProperty." + index.ToString(); + var index = dataTable.Columns.IndexOf(column); + var key = "ColumnMapping.Property." + index.ToString(); + if (form.AllKeys.Contains(key)) { + // allow to nil an entity property name to explicitly ignore a column var entityProperty = form[key]; - if (entityProperty.HasValue()) - { - if (map.Mappings.Any(x => x.Value.EntityProperty.IsCaseInsensitiveEqual(entityProperty))) - { - ModelState.AddModelError(key, T("Admin.DataExchange.ColumnMapping.Validate.EntityMultipleMapped", entityProperty)); - } + var defaultValue = form["ColumnMapping.Default." + index.ToString()]; - var defaultValue = form["ColumnMapping.DefaultValue." + index.ToString()]; - map.AddMapping(column.Name, entityProperty, defaultValue); - } + map.AddMapping(column.Name, null, entityProperty, defaultValue); + } + } + + // add model state error for invalid mappings + foreach (var invalidMapping in map.GetInvalidMappings()) + { + // do not mark columns as invalid where column name equals entity property name + if (invalidMapping.Key != invalidMapping.Value.Property) + { + var column = dataTable.Columns.First(x => x.Name == invalidMapping.Key); + var index = dataTable.Columns.IndexOf(column); + var key = "ColumnMapping.Property." + index.ToString(); + + ModelState.AddModelError(key, T("Admin.DataExchange.ColumnMapping.Validate.EntityMultipleMapped", invalidMapping.Value.Property)); } - ++index; } } diff --git a/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ImportProfileModel.cs b/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ImportProfileModel.cs index b45fd937c8..7310512284 100644 --- a/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ImportProfileModel.cs +++ b/src/Presentation/SmartStore.Web/Administration/Models/DataExchange/ImportProfileModel.cs @@ -56,10 +56,17 @@ public partial class ImportProfileModel : EntityModelBase public class ColumnMappingItemModel { public int Index { get; set; } + public bool IsNilProperty { get; set; } + public string Column { get; set; } public string ColumnWithoutIndex { get; set; } public string ColumnIndex { get; set; } - public string EntityProperty { get; set; } - public string DefaultValue { get; set; } + public string ColumnLocalized { get; set; } + + public string LanguageDescription { get; set; } + public string FlagImageFileName { get; set; } + + public string Property { get; set; } + public string Default { get; set; } } } \ No newline at end of file diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Import/_ColumnMappings.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Import/_ColumnMappings.cshtml index bc5bfd60b1..4dc8045232 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Import/_ColumnMappings.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Import/_ColumnMappings.cshtml @@ -19,8 +19,8 @@
@T("Admin.DataExchange.ColumnMapping.ImportField")@T("Admin.DataExchange.ColumnMapping.ImportFieldIndex")@T("Admin.DataExchange.ColumnMapping.EntityProperty")@T("Admin.DataExchange.ColumnMapping.ImportField")@T("Admin.DataExchange.ColumnMapping.ImportFieldIndex")@T("Admin.DataExchange.ColumnMapping.EntityProperty") @T("Admin.DataExchange.ColumnMapping.DefaultValue")
- @mapping.SourceColumn + @mapping.ColumnWithoutIndex - @mapping.SourceColumnIndex + @mapping.ColumnIndex - @Html.DropDownList("ColumnMappings.EntityProperty", mapping.AvailableEntityProperties, Model.UnspecifiedString) + +
+ @Html.ValidationMessage("ColumnMapping.EntityProperty." + mapping.Index.ToString())
- @Html.Editor("ColumnMappings.DefaultValue", mapping.DefaultValue) +
- - + + @@ -30,27 +30,46 @@ { } diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Import/_CreateOrUpdate.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Import/_CreateOrUpdate.cshtml index bd24686006..35f4e90cf8 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Import/_CreateOrUpdate.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Import/_CreateOrUpdate.cshtml @@ -200,15 +200,17 @@ function columnMappingSelectItemFormatting(item) { try { - var option = $(item.element); + if (item.text.length > 0) { + var option = $(item.element); - var html = '
' + item.text + ''; - if (option.length !== 0) { - html += ' (' + option.val() + ')'; - } - html += '
'; + var html = '
' + item.text + ''; + if (option.length !== 0) { + html += ' (' + option.val() + ')'; + } + html += '
'; - return html; + return html; + } } catch (e) { } diff --git a/src/Presentation/SmartStore.Web/Controllers/CommonController.cs b/src/Presentation/SmartStore.Web/Controllers/CommonController.cs index 877c920a2d..09ae5b0110 100644 --- a/src/Presentation/SmartStore.Web/Controllers/CommonController.cs +++ b/src/Presentation/SmartStore.Web/Controllers/CommonController.cs @@ -22,6 +22,7 @@ using SmartStore.Core.Domain.Tax; using SmartStore.Core.Domain.Themes; using SmartStore.Core.Infrastructure; +using SmartStore.Core.Localization; using SmartStore.Core.Themes; using SmartStore.Services; using SmartStore.Services.Catalog; @@ -158,7 +159,7 @@ protected LanguageSelectorModel PrepareLanguageSelectorModel() { Id = x.Id, Name = x.Name, - NativeName = GetLanguageNativeName(x.LanguageCulture) ?? x.Name, + NativeName = LocalizationHelper.GetLanguageNativeName(x.LanguageCulture) ?? x.Name, ISOCode = x.LanguageCulture, SeoCode = x.UniqueSeoCode, FlagImageFileName = x.FlagImageFileName @@ -200,28 +201,6 @@ protected LanguageSelectorModel PrepareLanguageSelectorModel() return model; } - // TODO: (MC) zentral auslagern - private string GetLanguageNativeName(string locale) - { - try - { - if (!string.IsNullOrEmpty(locale)) - { - var info = CultureInfo.GetCultureInfoByIetfLanguageTag(locale); - if (info == null) - { - return null; - } - return info.NativeName; - } - return null; - } - catch - { - return null; - } - } - [NonAction] protected CurrencySelectorModel PrepareCurrencySelectorModel() { diff --git a/src/Tests/SmartStore.Services.Tests/DataExchange/ImportDataSegmenterTests.cs b/src/Tests/SmartStore.Services.Tests/DataExchange/ImportDataSegmenterTests.cs index ceb0fb3d93..d36888d507 100644 --- a/src/Tests/SmartStore.Services.Tests/DataExchange/ImportDataSegmenterTests.cs +++ b/src/Tests/SmartStore.Services.Tests/DataExchange/ImportDataSegmenterTests.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Collections.Generic; using NUnit.Framework; using SmartStore.Core.Domain.Catalog; using SmartStore.Services.DataExchange.Import; @@ -28,7 +24,7 @@ public void CanResolveColumnIndexNames() }; var table = new LightweightDataTable(columns, new List()); - var segmenter = new ImportDataSegmenter(table); + var segmenter = new ImportDataSegmenter(table, new ColumnMap()); segmenter.ColumnMap.AddMapping("Attr[Material]", "material"); segmenter.ColumnMap.AddMapping("Name[it]", "name_it"); From 324a35b371036a7053ff18830e25b7a1990e8c43 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Fri, 25 Dec 2015 12:11:25 +0100 Subject: [PATCH 111/626] Removed a redundant HasColumn method --- .../Catalog/Importer/CategoryImporter.cs | 8 ++++---- .../Catalog/Importer/ProductImporter.cs | 12 ++++++------ .../DataExchange/Import/ImportDataSegmenter.cs | 4 ++-- .../DataExchange/Import/ImportExecuteContext.cs | 12 ------------ 4 files changed, 12 insertions(+), 24 deletions(-) diff --git a/src/Libraries/SmartStore.Services/Catalog/Importer/CategoryImporter.cs b/src/Libraries/SmartStore.Services/Catalog/Importer/CategoryImporter.cs index 50ffb37a4e..2b6bd7a2c3 100644 --- a/src/Libraries/SmartStore.Services/Catalog/Importer/CategoryImporter.cs +++ b/src/Libraries/SmartStore.Services/Catalog/Importer/CategoryImporter.cs @@ -65,7 +65,7 @@ private int ProcessSlugs(IImportExecuteContext context, ImportRow[] ba foreach (var row in batch) { - if (row.IsNew || row.NameChanged || row.Segmenter.HasDataColumn("SeName")) + if (row.IsNew || row.NameChanged || row.Segmenter.HasColumn("SeName")) { try { @@ -118,7 +118,7 @@ private int ProcessParentMappings(IImportExecuteContext context, foreach (var row in batch) { if (row.DataRow.TryGetValue("Id", out key1) && - row.Segmenter.HasDataColumn("ParentCategoryId") && row.DataRow.TryGetValue("ParentCategoryId", out key2)) + row.Segmenter.HasColumn("ParentCategoryId") && row.DataRow.TryGetValue("ParentCategoryId", out key2)) { var id = key1.ToString().ToInt(); var parentId = key2.ToString().ToInt(-1); @@ -176,7 +176,7 @@ private int ProcessCategories(IImportExecuteContext context, if (category == null) { // a Name is required with new categories - if (!row.Segmenter.HasDataColumn("Name")) + if (!row.Segmenter.HasColumn("Name")) { context.Result.AddError("The 'Name' field is required for new categories. Skipping row.", row.GetRowInfo(), "Name"); continue; @@ -333,7 +333,7 @@ public void Execute(IImportExecuteContext context) context.Result.NewRecords += batch.Count(x => x.IsNew && !x.IsTransient); context.Result.ModifiedRecords += batch.Count(x => !x.IsNew && !x.IsTransient); - if (context.HasColumn("SeName") || batch.Any(x => x.IsNew || x.NameChanged)) + if (segmenter.HasColumn("SeName") || batch.Any(x => x.IsNew || x.NameChanged)) { try { diff --git a/src/Libraries/SmartStore.Services/Catalog/Importer/ProductImporter.cs b/src/Libraries/SmartStore.Services/Catalog/Importer/ProductImporter.cs index dba41684e4..f3aafc0f6f 100644 --- a/src/Libraries/SmartStore.Services/Catalog/Importer/ProductImporter.cs +++ b/src/Libraries/SmartStore.Services/Catalog/Importer/ProductImporter.cs @@ -323,7 +323,7 @@ private int ProcessSlugs(IImportExecuteContext context, ImportRow[] bat foreach (var row in batch) { - if (row.IsNew || row.NameChanged || row.Segmenter.HasDataColumn("SeName")) + if (row.IsNew || row.NameChanged || row.Segmenter.HasColumn("SeName")) { try { @@ -400,7 +400,7 @@ private int ProcessProducts(IImportExecuteContext context, ImportRow[] if (product == null) { // a Name is required with new products. - if (!row.Segmenter.HasDataColumn("Name")) + if (!row.Segmenter.HasColumn("Name")) { context.Result.AddError("The 'Name' field is required for new products. Skipping row.", row.GetRowInfo(), "Name"); continue; @@ -581,7 +581,7 @@ public void Execute(IImportExecuteContext context) // IMPORTANT: Unlike with Products AutoCommitEnabled must be TRUE, // as Slugs are going to be validated against existing ones in DB. // =========================================================================== - if (context.HasColumn("SeName") || batch.Any(x => x.IsNew || x.NameChanged)) + if (segmenter.HasColumn("SeName") || batch.Any(x => x.IsNew || x.NameChanged)) { try { @@ -613,7 +613,7 @@ public void Execute(IImportExecuteContext context) // =========================================================================== // 4.) Import product category mappings // =========================================================================== - if (context.HasColumn("CategoryIds")) + if (segmenter.HasColumn("CategoryIds")) { try { @@ -628,7 +628,7 @@ public void Execute(IImportExecuteContext context) // =========================================================================== // 5.) Import product manufacturer mappings // =========================================================================== - if (context.HasColumn("ManufacturerIds")) + if (segmenter.HasColumn("ManufacturerIds")) { try { @@ -643,7 +643,7 @@ public void Execute(IImportExecuteContext context) // =========================================================================== // 6.) Import product picture mappings // =========================================================================== - if (context.HasColumn("PictureThumbPaths")) + if (segmenter.HasColumn("PictureThumbPaths")) { try { diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportDataSegmenter.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportDataSegmenter.cs index 991398d73f..7ca1197f0f 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportDataSegmenter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportDataSegmenter.cs @@ -88,12 +88,12 @@ public int BatchSize get { return BATCHSIZE; } } - public bool HasDataColumn(string name) + public bool HasColumn(string name) { return _table.HasColumn(_columnMap.GetMappedProperty(name)); } - public bool HasDataColumn(string name, string index) + public bool HasColumn(string name, string index) { return _table.HasColumn(_columnMap.GetMappedProperty(name, index)); } diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportExecuteContext.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportExecuteContext.cs index 3a0ebe03a2..79562488d6 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportExecuteContext.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportExecuteContext.cs @@ -35,13 +35,6 @@ public interface IImportExecuteContext /// ImportDataSegmenter GetSegmenter() where TEntity : BaseEntity; - /// - /// Whether the data source contains a particular column - /// - /// - /// - bool HasColumn(string name); - /// /// Allows to set a progress message /// @@ -112,11 +105,6 @@ public ImportDataSegmenter GetSegmenter() where TEntity : Base return new ImportDataSegmenter(DataTable, ColumnMap); } - public bool HasColumn(string name) - { - return DataTable.HasColumn(name); - } - public void SetProgress(int value, int maximum) { try From 8244642b9ef38f49a798ed394bdebb4867e43549 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Fri, 25 Dec 2015 12:53:24 +0100 Subject: [PATCH 112/626] Removed ImportRow.DataRow property because Importer would get round default value handling here. --- .../Catalog/Importer/CategoryImporter.cs | 80 +++++++------------ .../Catalog/Importer/ProductImporter.cs | 20 ++--- .../Customers/Importer/CustomerImporter.cs | 27 +++---- .../DataExchange/Import/ImportRow.cs | 5 -- 4 files changed, 47 insertions(+), 85 deletions(-) diff --git a/src/Libraries/SmartStore.Services/Catalog/Importer/CategoryImporter.cs b/src/Libraries/SmartStore.Services/Catalog/Importer/CategoryImporter.cs index 2b6bd7a2c3..a547f07928 100644 --- a/src/Libraries/SmartStore.Services/Catalog/Importer/CategoryImporter.cs +++ b/src/Libraries/SmartStore.Services/Catalog/Importer/CategoryImporter.cs @@ -113,26 +113,21 @@ private int ProcessParentMappings(IImportExecuteContext context, ImportRow[] batch, Dictionary oldToNewId) { - object key1, key2; - foreach (var row in batch) { - if (row.DataRow.TryGetValue("Id", out key1) && - row.Segmenter.HasColumn("ParentCategoryId") && row.DataRow.TryGetValue("ParentCategoryId", out key2)) - { - var id = key1.ToString().ToInt(); - var parentId = key2.ToString().ToInt(-1); + var id = row.GetDataValue("Id"); + var rawParentId = row.GetDataValue("ParentCategoryId"); + var parentId = rawParentId.ToInt(-1); - if (id != 0 && parentId != -1 && oldToNewId.ContainsKey(id) && oldToNewId.ContainsKey(parentId)) + if (id != 0 && parentId != -1 && oldToNewId.ContainsKey(id) && oldToNewId.ContainsKey(parentId)) + { + // only touch hierarchical data if child and parent were inserted + if (oldToNewId[id].Inserted && oldToNewId[parentId].Inserted && oldToNewId[id].NewId != 0) { - // only touch hierarchical data if child and parent were inserted - if (oldToNewId[id].Inserted && oldToNewId[parentId].Inserted && oldToNewId[id].NewId != 0) + var category = _categoryRepository.GetById(oldToNewId[id].NewId); + if (category != null) { - var category = _categoryRepository.GetById(oldToNewId[id].NewId); - if (category != null) - { - category.ParentCategoryId = oldToNewId[parentId].NewId; - } + category.ParentCategoryId = oldToNewId[parentId].NewId; } } } @@ -151,7 +146,6 @@ private int ProcessCategories(IImportExecuteContext context, { _categoryRepository.AutoCommitEnabled = true; - object key; Picture picture = null; Category lastInserted = null; Category lastUpdated = null; @@ -161,16 +155,11 @@ private int ProcessCategories(IImportExecuteContext context, foreach (var row in batch) { Category category = null; - var id = 0; + var id = row.GetDataValue("Id"); - // try get by int ID - if (row.DataRow.TryGetValue("Id", out key)) + if (id != 0) { - id = key.ToString().ToInt(); - if (id != 0) - { - category = _categoryRepository.GetById(id); - } + category = _categoryRepository.GetById(id); } if (category == null) @@ -216,11 +205,10 @@ private int ProcessCategories(IImportExecuteContext context, row.SetProperty(context.Result, category, (x) => x.Alias); row.SetProperty(context.Result, category, (x) => x.DefaultViewMode); - if (row.DataRow.TryGetValue("CategoryTemplateId", out key)) + var templateId = row.GetDataValue("CategoryTemplateId"); + if (templateId > 0 && allCategoryTemplateIds.Contains(templateId)) { - int templateId = key.ToString().ToInt(); - if (templateId > 0 && allCategoryTemplateIds.Contains(templateId)) - category.CategoryTemplateId = templateId; + category.CategoryTemplateId = templateId; } var storeIds = row.GetDataValue>("StoreIds"); @@ -229,26 +217,22 @@ private int ProcessCategories(IImportExecuteContext context, _storeMappingService.SaveStoreMappings(category, storeIds.ToArray()); } - if (row.DataRow.TryGetValue("PictureThumbPath", out key)) + var thumbPath = row.GetDataValue("PictureThumbPath"); + if (thumbPath.HasValue() && File.Exists(thumbPath)) { - var thumbPath = key.ToString(); - if (thumbPath.HasValue() && File.Exists(thumbPath)) - { - var pictures = new List(); - if (category.PictureId.HasValue && (picture = _pictureRepository.GetById(category.PictureId.Value)) != null) - pictures.Add(picture); + var pictures = new List(); + if (category.PictureId.HasValue && (picture = _pictureRepository.GetById(category.PictureId.Value)) != null) + pictures.Add(picture); - var pictureBinary = _pictureService.FindEqualPicture(thumbPath, pictures, out equalPictureId); + var pictureBinary = _pictureService.FindEqualPicture(thumbPath, pictures, out equalPictureId); - if (pictureBinary != null && pictureBinary.Length > 0 && - (picture = _pictureService.InsertPicture(pictureBinary, "image/jpeg", _pictureService.GetPictureSeName(row.EntityDisplayName), true, false, false)) != null) - { - category.PictureId = picture.Id; - } + if (pictureBinary != null && pictureBinary.Length > 0 && + (picture = _pictureService.InsertPicture(pictureBinary, "image/jpeg", _pictureService.GetPictureSeName(row.EntityDisplayName), true, false, false)) != null) + { + category.PictureId = picture.Id; } } - row.SetProperty(context.Result, category, (x) => x.CreatedOnUtc, utcNow); category.UpdatedOnUtc = utcNow; @@ -275,12 +259,10 @@ private int ProcessCategories(IImportExecuteContext context, // get new category ids foreach (var row in batch) { - if (row.DataRow.TryGetValue("Id", out key)) - { - var id = key.ToString().ToInt(); - if (id != 0 && oldToNewId.ContainsKey(id)) - oldToNewId[id].NewId = row.Entity.Id; - } + var id = row.GetDataValue("Id"); + + if (id != 0 && oldToNewId.ContainsKey(id)) + oldToNewId[id].NewId = row.Entity.Id; } // Perf: notify only about LAST insertion and update @@ -352,7 +334,7 @@ public void Execute(IImportExecuteContext context) } // map parent id of inserted categories - if (oldToNewId.Any()) + if (oldToNewId.Any() && segmenter.HasColumn("Id") && segmenter.HasColumn("ParentCategoryId")) { segmenter.Reset(); diff --git a/src/Libraries/SmartStore.Services/Catalog/Importer/ProductImporter.cs b/src/Libraries/SmartStore.Services/Catalog/Importer/ProductImporter.cs index f3aafc0f6f..b115a270eb 100644 --- a/src/Libraries/SmartStore.Services/Catalog/Importer/ProductImporter.cs +++ b/src/Libraries/SmartStore.Services/Catalog/Importer/ProductImporter.cs @@ -376,25 +376,17 @@ private int ProcessProducts(IImportExecuteContext context, ImportRow[] foreach (var row in batch) { - Product product = null; - object key; - - // try get by int ID - if (row.DataRow.TryGetValue("Id", out key) && key.ToString().ToInt() > 0) - { - product = _productService.GetProductById(key.ToString().ToInt()); - } + var id = row.GetDataValue("Id"); + var product = _productService.GetProductById(id); - // try get by SKU - if (product == null && row.DataRow.TryGetValue("SKU", out key)) + if (product == null) { - product = _productService.GetProductBySku(key.ToString()); + product = _productService.GetProductBySku(row.GetDataValue("Sku")); } - // try get by GTIN - if (product == null && row.DataRow.TryGetValue("Gtin", out key)) + if (product == null) { - product = _productService.GetProductByGtin(key.ToString()); + product = _productService.GetProductByGtin(row.GetDataValue("Gtin")); } if (product == null) diff --git a/src/Libraries/SmartStore.Services/Customers/Importer/CustomerImporter.cs b/src/Libraries/SmartStore.Services/Customers/Importer/CustomerImporter.cs index e486a5c7f0..f148f2cd6b 100644 --- a/src/Libraries/SmartStore.Services/Customers/Importer/CustomerImporter.cs +++ b/src/Libraries/SmartStore.Services/Customers/Importer/CustomerImporter.cs @@ -180,19 +180,14 @@ private int ProcessCustomers(IImportExecuteContext context, foreach (var row in batch) { - object key; - var customerId = 0; - Customer customer = null; + var id = row.GetDataValue("Id"); + var customer = _customerService.GetCustomerById(id); - if (row.DataRow.TryGetValue("Id", out key) && key.ToString().ToInt() > 0) - { - customerId = key.ToString().ToInt(); - customer = _customerService.GetCustomerById(customerId); - } - - if (customer == null && row.DataRow.TryGetValue("CustomerGuid", out key)) + if (customer == null) { - customer = _customerService.GetCustomerByGuid(new Guid(key.ToString())); + var guid = row.GetDataValue("CustomerGuid"); + if (guid.HasValue()) + customer = _customerService.GetCustomerByGuid(new Guid(guid)); } if (customer == null) @@ -214,8 +209,9 @@ private int ProcessCustomers(IImportExecuteContext context, var isRegistered = row.GetDataValue("IsRegistered"); var isAdmin = row.GetDataValue("IsAdministrator"); var isForumModerator = row.GetDataValue("IsForumModerator"); + var affiliateId = row.GetDataValue("AffiliateId"); - row.Initialize(customer, email.HasValue() ? email : customerId.ToString()); + row.Initialize(customer, email.HasValue() ? email : id.ToString()); row.SetProperty(context.Result, customer, (x) => x.CustomerGuid); row.SetProperty(context.Result, customer, (x) => x.Username); @@ -235,14 +231,11 @@ private int ProcessCustomers(IImportExecuteContext context, row.SetProperty(context.Result, customer, (x) => x.CreatedOnUtc, utcNow); row.SetProperty(context.Result, customer, (x) => x.LastActivityDateUtc, utcNow); - if (row.DataRow.TryGetValue("AffiliateId", out key)) + if (affiliateId > 0 && allAffiliateIds.Contains(affiliateId)) { - int affiliateId = key.ToString().ToInt(); - if (affiliateId > 0 && allAffiliateIds.Contains(affiliateId)) - customer.AffiliateId = affiliateId; + customer.AffiliateId = affiliateId; } - UpsertRole(row, guestRole, SystemCustomerRoleNames.Guests, isGuest); UpsertRole(row, registeredRole, SystemCustomerRoleNames.Registered, isRegistered); UpsertRole(row, adminRole, SystemCustomerRoleNames.Administrators, isAdmin); diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportRow.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportRow.cs index 662d4c32b5..33279b7d7b 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportRow.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportRow.cs @@ -73,11 +73,6 @@ public bool IsNew get { return _isNew; } } - public IDataRow DataRow - { - get { return _row; } - } - public ImportDataSegmenter Segmenter { get { return _segmenter; } From 10155563a180c74c6ba2e20665ecd4ca064fb7f8 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Fri, 25 Dec 2015 19:12:20 +0100 Subject: [PATCH 113/626] Testing importers --- .../Catalog/Importer/CategoryImporter.cs | 119 +++++++++++++----- .../Controllers/ImportController.cs | 19 +-- .../Administration/SmartStore.Admin.csproj | 1 - .../Views/Import/_CreateOrUpdate.cshtml | 37 +++--- .../Views/Import/_ImportFileList.cshtml | 13 -- 5 files changed, 113 insertions(+), 76 deletions(-) delete mode 100644 src/Presentation/SmartStore.Web/Administration/Views/Import/_ImportFileList.cshtml diff --git a/src/Libraries/SmartStore.Services/Catalog/Importer/CategoryImporter.cs b/src/Libraries/SmartStore.Services/Catalog/Importer/CategoryImporter.cs index a547f07928..08c0223ee6 100644 --- a/src/Libraries/SmartStore.Services/Catalog/Importer/CategoryImporter.cs +++ b/src/Libraries/SmartStore.Services/Catalog/Importer/CategoryImporter.cs @@ -111,7 +111,7 @@ private int ProcessSlugs(IImportExecuteContext context, ImportRow[] ba private int ProcessParentMappings(IImportExecuteContext context, ImportRow[] batch, - Dictionary oldToNewId) + Dictionary srcToDestId) { foreach (var row in batch) { @@ -119,15 +119,55 @@ private int ProcessParentMappings(IImportExecuteContext context, var rawParentId = row.GetDataValue("ParentCategoryId"); var parentId = rawParentId.ToInt(-1); - if (id != 0 && parentId != -1 && oldToNewId.ContainsKey(id) && oldToNewId.ContainsKey(parentId)) + if (id != 0 && parentId != -1 && srcToDestId.ContainsKey(id) && srcToDestId.ContainsKey(parentId)) { // only touch hierarchical data if child and parent were inserted - if (oldToNewId[id].Inserted && oldToNewId[parentId].Inserted && oldToNewId[id].NewId != 0) + if (srcToDestId[id].Inserted && srcToDestId[parentId].Inserted && srcToDestId[id].DestinationId != 0) { - var category = _categoryRepository.GetById(oldToNewId[id].NewId); + var category = _categoryRepository.GetById(srcToDestId[id].DestinationId); if (category != null) { - category.ParentCategoryId = oldToNewId[parentId].NewId; + category.ParentCategoryId = srcToDestId[parentId].DestinationId; + } + } + } + } + + var num = _categoryRepository.Context.SaveChanges(); + + return num; + } + + private int ProcessPictures(IImportExecuteContext context, + ImportRow[] batch, + Dictionary srcToDestId) + { + Picture picture = null; + var equalPictureId = 0; + + foreach (var row in batch) + { + var srcId = row.GetDataValue("Id"); + var thumbPath = row.GetDataValue("PictureThumbPath"); + + if (srcId != 0 && srcToDestId.ContainsKey(srcId) && thumbPath.HasValue() && File.Exists(thumbPath)) + { + var category = _categoryRepository.GetById(srcToDestId[srcId].DestinationId); + + if (category != null) + { + var pictures = new List(); + if (category.PictureId.HasValue && (picture = _pictureRepository.GetById(category.PictureId.Value)) != null) + pictures.Add(picture); + + var pictureBinary = _pictureService.FindEqualPicture(thumbPath, pictures, out equalPictureId); + + if (pictureBinary != null && pictureBinary.Length > 0 && + (picture = _pictureService.InsertPicture(pictureBinary, "image/jpeg", _pictureService.GetPictureSeName(row.EntityDisplayName), true, false, false)) != null) + { + category.PictureId = picture.Id; + + _categoryRepository.Update(category); } } } @@ -142,14 +182,14 @@ private int ProcessCategories(IImportExecuteContext context, ImportRow[] batch, DateTime utcNow, List allCategoryTemplateIds, - Dictionary oldToNewId) + Dictionary srcToDestId) { _categoryRepository.AutoCommitEnabled = true; - Picture picture = null; + //Picture picture = null; Category lastInserted = null; Category lastUpdated = null; - var equalPictureId = 0; + //var equalPictureId = 0; var defaultTemplateId = allCategoryTemplateIds.First(); foreach (var row in batch) @@ -217,28 +257,28 @@ private int ProcessCategories(IImportExecuteContext context, _storeMappingService.SaveStoreMappings(category, storeIds.ToArray()); } - var thumbPath = row.GetDataValue("PictureThumbPath"); - if (thumbPath.HasValue() && File.Exists(thumbPath)) - { - var pictures = new List(); - if (category.PictureId.HasValue && (picture = _pictureRepository.GetById(category.PictureId.Value)) != null) - pictures.Add(picture); + //var thumbPath = row.GetDataValue("PictureThumbPath"); + //if (thumbPath.HasValue() && File.Exists(thumbPath)) + //{ + // var pictures = new List(); + // if (category.PictureId.HasValue && (picture = _pictureRepository.GetById(category.PictureId.Value)) != null) + // pictures.Add(picture); - var pictureBinary = _pictureService.FindEqualPicture(thumbPath, pictures, out equalPictureId); + // var pictureBinary = _pictureService.FindEqualPicture(thumbPath, pictures, out equalPictureId); - if (pictureBinary != null && pictureBinary.Length > 0 && - (picture = _pictureService.InsertPicture(pictureBinary, "image/jpeg", _pictureService.GetPictureSeName(row.EntityDisplayName), true, false, false)) != null) - { - category.PictureId = picture.Id; - } - } + // if (pictureBinary != null && pictureBinary.Length > 0 && + // (picture = _pictureService.InsertPicture(pictureBinary, "image/jpeg", _pictureService.GetPictureSeName(row.EntityDisplayName), true, false, false)) != null) + // { + // category.PictureId = picture.Id; + // } + //} row.SetProperty(context.Result, category, (x) => x.CreatedOnUtc, utcNow); category.UpdatedOnUtc = utcNow; - if (id != 0 && !oldToNewId.ContainsKey(id)) + if (id != 0 && !srcToDestId.ContainsKey(id)) { - oldToNewId.Add(id, new ImportCategoryMapping { Inserted = row.IsTransient }); + srcToDestId.Add(id, new ImportCategoryMapping { Inserted = row.IsTransient }); } if (row.IsTransient) @@ -261,8 +301,8 @@ private int ProcessCategories(IImportExecuteContext context, { var id = row.GetDataValue("Id"); - if (id != 0 && oldToNewId.ContainsKey(id)) - oldToNewId[id].NewId = row.Entity.Id; + if (id != 0 && srcToDestId.ContainsKey(id)) + srcToDestId[id].DestinationId = row.Entity.Id; } // Perf: notify only about LAST insertion and update @@ -277,7 +317,7 @@ private int ProcessCategories(IImportExecuteContext context, public void Execute(IImportExecuteContext context) { var utcNow = DateTime.UtcNow; - var oldToNewId = new Dictionary(); + var srcToDestId = new Dictionary(); var allCategoryTemplateIds = _categoryTemplateService.GetAllCategoryTemplates() .Select(x => x.Id) @@ -300,7 +340,7 @@ public void Execute(IImportExecuteContext context) try { - ProcessCategories(context, batch, utcNow, allCategoryTemplateIds, oldToNewId); + ProcessCategories(context, batch, utcNow, allCategoryTemplateIds, srcToDestId); } catch (Exception exception) { @@ -315,6 +355,7 @@ public void Execute(IImportExecuteContext context) context.Result.NewRecords += batch.Count(x => x.IsNew && !x.IsTransient); context.Result.ModifiedRecords += batch.Count(x => !x.IsNew && !x.IsTransient); + // process slugs if (segmenter.HasColumn("SeName") || batch.Any(x => x.IsNew || x.NameChanged)) { try @@ -331,10 +372,28 @@ public void Execute(IImportExecuteContext context) _categoryRepository.Context.AutoDetectChangesEnabled = false; } } + + // process pictures + if (srcToDestId.Any() && segmenter.HasColumn("PictureThumbPath")) + { + try + { + _categoryRepository.Context.AutoDetectChangesEnabled = true; + ProcessPictures(context, batch, srcToDestId); + } + catch (Exception exception) + { + context.Result.AddError(exception, segmenter.CurrentSegment, "ProcessPictures"); + } + finally + { + _categoryRepository.Context.AutoDetectChangesEnabled = false; + } + } } // map parent id of inserted categories - if (oldToNewId.Any() && segmenter.HasColumn("Id") && segmenter.HasColumn("ParentCategoryId")) + if (srcToDestId.Any() && segmenter.HasColumn("Id") && segmenter.HasColumn("ParentCategoryId")) { segmenter.Reset(); @@ -346,7 +405,7 @@ public void Execute(IImportExecuteContext context) try { - ProcessParentMappings(context, batch, oldToNewId); + ProcessParentMappings(context, batch, srcToDestId); } catch (Exception exception) { @@ -361,7 +420,7 @@ public void Execute(IImportExecuteContext context) internal class ImportCategoryMapping { - public int NewId { get; set; } + public int DestinationId { get; set; } public bool Inserted { get; set; } } } diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs index 11418e16e9..9c2d6b565f 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs @@ -399,7 +399,6 @@ public JsonResult FileUpload(int id) var success = false; string error = null; string tempFile = ""; - string fileList = ""; if (_services.Permissions.Authorize(StandardPermissionProvider.ManageImports)) { @@ -436,14 +435,6 @@ public JsonResult FileUpload(int id) var destFile = Path.Combine(folder, Path.GetFileName(postedFile.FileName)); success = postedFile.Stream.ToFile(destFile); - - if (success) - { - var model = new ImportProfileModel(); - PrepareProfileModel(model, profile, false); - - fileList = this.RenderPartialViewToString("_ImportFileList", model); - } } } } @@ -460,7 +451,7 @@ public JsonResult FileUpload(int id) if (error.HasValue()) NotifyError(error); - return Json(new { success = success, tempFile = tempFile, fileList = fileList }); + return Json(new { success = success, tempFile = tempFile }); } [HttpPost] @@ -522,6 +513,7 @@ public ActionResult DownloadImportFile(int id, string name) return result; } + [HttpPost] public ActionResult DeleteImportFile(int id, string name) { if (_services.Permissions.Authorize(StandardPermissionProvider.ManageImports)) @@ -531,14 +523,9 @@ public ActionResult DeleteImportFile(int id, string name) { var path = Path.Combine(profile.GetImportFolder(true), name); FileSystemHelper.Delete(path); - - var model = new ImportProfileModel(); - PrepareProfileModel(model, profile, false); - - return PartialView("_ImportFileList", model); } } - return new EmptyResult(); + return RedirectToAction("Edit", new { id = id }); } } } \ No newline at end of file diff --git a/src/Presentation/SmartStore.Web/Administration/SmartStore.Admin.csproj b/src/Presentation/SmartStore.Web/Administration/SmartStore.Admin.csproj index 5b0852f437..8aa8fd5f3f 100644 --- a/src/Presentation/SmartStore.Web/Administration/SmartStore.Admin.csproj +++ b/src/Presentation/SmartStore.Web/Administration/SmartStore.Admin.csproj @@ -542,7 +542,6 @@ - diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Import/_CreateOrUpdate.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Import/_CreateOrUpdate.cshtml index 35f4e90cf8..2212f50131 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Import/_CreateOrUpdate.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Import/_CreateOrUpdate.cshtml @@ -39,12 +39,22 @@ - + @if (Model.ScheduleTaskId > 0) @@ -152,9 +162,8 @@ $('#ImportFileList').html(data.result.tempFile); $('#ImportFileUploadContainer').hide(); // just one initial file to specify the file type } - - if (!_.isEmpty(data.result.fileList)) { - $('#ImportFileList').html(data.result.fileList); + else { + location.href = '@Url.Action("Edit", new { id = Model.Id })'; } } } @@ -163,17 +172,13 @@ // delete import file $('#ImportFileList').on('click', '.import-file-delete', function (e) { e.preventDefault(); - var url = '@Url.Action("DeleteImportFile", new { id = Model.Id })'; - - $({}).doAjax({ - type: 'POST', - url: url + '?name=' + encodeURIComponent($(this).attr('data-filename')), - ask: '@T("Admin.Common.AreYouSure")', - callbackSuccess: function (resp) { - if (!_.isEmpty(resp)) - $('#ImportFileList').html(resp); - } - }); + + if (confirm('@T("Admin.Common.AskToProceed")')) { + var form = ''; + $('body').append(form); + $('#DeleteImportFileForm').submit(); + } + return false; }); diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Import/_ImportFileList.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Import/_ImportFileList.cshtml deleted file mode 100644 index be0f5d9703..0000000000 --- a/src/Presentation/SmartStore.Web/Administration/Views/Import/_ImportFileList.cshtml +++ /dev/null @@ -1,13 +0,0 @@ -@using SmartStore.Admin.Models.DataExchange; -@model ImportProfileModel -@foreach (var fileName in Model.ExistingFileNames) -{ -

- @Html.IconForFileExtension(Path.GetExtension(fileName), false) - @fileName - - -

-} \ No newline at end of file From f33cfa4c2df887f3c661d3a05539dbd2e203e07d Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Fri, 25 Dec 2015 19:41:15 +0100 Subject: [PATCH 114/626] Hide export profiles where the provider is decorated with hidden attribute --- .../Controllers/ExportController.cs | 49 ++++++++++++++++--- 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs index 32f84d8afd..2e719959ec 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs @@ -488,13 +488,17 @@ public ActionResult List() foreach (var profile in profiles) { - var profileModel = new ExportProfileModel(); + var provider = providers.FirstOrDefault(x => x.Metadata.SystemName == profile.ProviderSystemName); + if (provider != null) + { + var profileModel = new ExportProfileModel(); - PrepareProfileModel(profileModel, profile, providers.FirstOrDefault(x => x.Metadata.SystemName == profile.ProviderSystemName), false); + PrepareProfileModel(profileModel, profile, provider, false); - profileModel.TaskModel = profile.ScheduleTask.ToScheduleTaskModel(_services.Localization, _dateTimeHelper, Url); + profileModel.TaskModel = profile.ScheduleTask.ToScheduleTaskModel(_services.Localization, _dateTimeHelper, Url); - model.Add(profileModel); + model.Add(profileModel); + } } return View(model); @@ -613,6 +617,8 @@ public ActionResult Edit(int id) return RedirectToAction("List"); var provider = _exportService.LoadProvider(profile.ProviderSystemName); + if (provider.Metadata.IsHidden) + return RedirectToAction("List"); var model = new ExportProfileModel(); @@ -634,6 +640,8 @@ public ActionResult Edit(ExportProfileModel model, bool continueEditing) return RedirectToAction("List"); var provider = _exportService.LoadProvider(profile.ProviderSystemName); + if (provider.Metadata.IsHidden) + return RedirectToAction("List"); if (!ModelState.IsValid) { @@ -754,6 +762,10 @@ public ActionResult DeleteConfirmed(int id) if (profile == null) return RedirectToAction("List"); + var provider = _exportService.LoadProvider(profile.ProviderSystemName); + if (provider.Metadata.IsHidden) + return RedirectToAction("List"); + try { _exportService.DeleteExportProfile(profile); @@ -779,6 +791,10 @@ public ActionResult Preview(int id) if (profile == null) return RedirectToAction("List"); + var provider = _exportService.LoadProvider(profile.ProviderSystemName); + if (provider.Metadata.IsHidden) + return RedirectToAction("List"); + if (!profile.Enabled) { NotifyInfo(T("Admin.DataExchange.Export.EnableProfileForPreview")); @@ -786,8 +802,6 @@ public ActionResult Preview(int id) return RedirectToAction("Edit", new { id = profile.Id }); } - var provider = _exportService.LoadProvider(profile.ProviderSystemName); - var request = new DataExportRequest(profile, provider); var totalRecords = _dataExporter.GetDataCount(request); @@ -814,7 +828,8 @@ public ActionResult PreviewList(GridCommand command, int id, int totalRecords) if (_services.Permissions.Authorize(StandardPermissionProvider.ManageExports) && (profile = _exportService.GetExportProfileById(id)) != null && - (provider = _exportService.LoadProvider(profile.ProviderSystemName)) != null) + (provider = _exportService.LoadProvider(profile.ProviderSystemName)) != null && + !provider.Metadata.IsHidden) { var productModel = new List(); var orderModel = new List(); @@ -981,6 +996,10 @@ public ActionResult Execute(int id, string selectedIds) if (profile == null) return RedirectToAction("List"); + var provider = _exportService.LoadProvider(profile.ProviderSystemName); + if (provider.Metadata.IsHidden) + return RedirectToAction("List"); + var taskParams = new Dictionary(); taskParams.Add("CurrentCustomerId", _services.WorkContext.CurrentCustomer.Id.ToString()); @@ -1090,6 +1109,8 @@ public ActionResult CreateDeployment(int id) return RedirectToAction("List"); var provider = _exportService.LoadProvider(profile.ProviderSystemName); + if (provider.Metadata.IsHidden) + return RedirectToAction("List"); //var fileSystemName = ExportDeploymentType.FileSystem.GetLocalizedEnum(_services.Localization, _services.WorkContext); @@ -1115,6 +1136,10 @@ public ActionResult CreateDeployment(ExportDeploymentModel model, bool continueE if (profile == null) return RedirectToAction("List"); + var provider = _exportService.LoadProvider(profile.ProviderSystemName); + if (provider.Metadata.IsHidden) + return RedirectToAction("List"); + if (ModelState.IsValid) { var deployment = new ExportDeployment(); @@ -1141,6 +1166,8 @@ public ActionResult EditDeployment(int id) return RedirectToAction("List"); var provider = _exportService.LoadProvider(deployment.Profile.ProviderSystemName); + if (provider.Metadata.IsHidden) + return RedirectToAction("List"); var model = PrepareDeploymentModel(deployment, provider, true); @@ -1158,6 +1185,10 @@ public ActionResult EditDeployment(ExportDeploymentModel model, bool continueEdi if (deployment == null) return RedirectToAction("List"); + var provider = _exportService.LoadProvider(deployment.Profile.ProviderSystemName); + if (provider.Metadata.IsHidden) + return RedirectToAction("List"); + if (ModelState.IsValid) { ModelToEntity(model, deployment); @@ -1183,6 +1214,10 @@ public ActionResult DeleteDeployment(int id) if (deployment == null) return RedirectToAction("List"); + var provider = _exportService.LoadProvider(deployment.Profile.ProviderSystemName); + if (provider.Metadata.IsHidden) + return RedirectToAction("List"); + int profileId = deployment.ProfileId; _exportService.DeleteExportDeployment(deployment); From 77221c4bbf26dd00f93ea149987bcb71a8a85930 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Sat, 26 Dec 2015 11:24:27 +0100 Subject: [PATCH 115/626] Minor changes --- .../Catalog/Importer/CategoryImporter.cs | 18 ------------------ .../DataExchange/DataExporter.cs | 3 +++ .../DataExchange/IDataExporter.cs | 1 + 3 files changed, 4 insertions(+), 18 deletions(-) diff --git a/src/Libraries/SmartStore.Services/Catalog/Importer/CategoryImporter.cs b/src/Libraries/SmartStore.Services/Catalog/Importer/CategoryImporter.cs index 08c0223ee6..e0e5a2bdf2 100644 --- a/src/Libraries/SmartStore.Services/Catalog/Importer/CategoryImporter.cs +++ b/src/Libraries/SmartStore.Services/Catalog/Importer/CategoryImporter.cs @@ -186,10 +186,8 @@ private int ProcessCategories(IImportExecuteContext context, { _categoryRepository.AutoCommitEnabled = true; - //Picture picture = null; Category lastInserted = null; Category lastUpdated = null; - //var equalPictureId = 0; var defaultTemplateId = allCategoryTemplateIds.First(); foreach (var row in batch) @@ -257,22 +255,6 @@ private int ProcessCategories(IImportExecuteContext context, _storeMappingService.SaveStoreMappings(category, storeIds.ToArray()); } - //var thumbPath = row.GetDataValue("PictureThumbPath"); - //if (thumbPath.HasValue() && File.Exists(thumbPath)) - //{ - // var pictures = new List(); - // if (category.PictureId.HasValue && (picture = _pictureRepository.GetById(category.PictureId.Value)) != null) - // pictures.Add(picture); - - // var pictureBinary = _pictureService.FindEqualPicture(thumbPath, pictures, out equalPictureId); - - // if (pictureBinary != null && pictureBinary.Length > 0 && - // (picture = _pictureService.InsertPicture(pictureBinary, "image/jpeg", _pictureService.GetPictureSeName(row.EntityDisplayName), true, false, false)) != null) - // { - // category.PictureId = picture.Id; - // } - //} - row.SetProperty(context.Result, category, (x) => x.CreatedOnUtc, utcNow); category.UpdatedOnUtc = utcNow; diff --git a/src/Libraries/SmartStore.Services/DataExchange/DataExporter.cs b/src/Libraries/SmartStore.Services/DataExchange/DataExporter.cs index d8d3006017..5a6d2268d3 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/DataExporter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/DataExporter.cs @@ -202,6 +202,9 @@ private void SetProgress(DataExporterContext ctx, string message) private bool HasPermission(DataExporterContext ctx) { + if (ctx.Request.HasPermission) + return true; + if (ctx.Request.CustomerId == 0) ctx.Request.CustomerId = _services.WorkContext.CurrentCustomer.Id; // fallback to background task system customer diff --git a/src/Libraries/SmartStore.Services/DataExchange/IDataExporter.cs b/src/Libraries/SmartStore.Services/DataExchange/IDataExporter.cs index 8e30fa9974..97f7cec7f1 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/IDataExporter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/IDataExporter.cs @@ -43,6 +43,7 @@ public DataExportRequest(ExportProfile profile, Provider provid public ProgressValueSetter ProgressValueSetter { get; set; } public int CustomerId { get; set; } + public bool HasPermission { get; set; } public IList EntitiesToExport { get; set; } From a70471841a8bc6db38da69abd5f9a8fcc42d7a52 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Sat, 26 Dec 2015 11:35:56 +0100 Subject: [PATCH 116/626] Updated changelog --- changelog.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/changelog.md b/changelog.md index 6294b6d91e..3d69214836 100644 --- a/changelog.md +++ b/changelog.md @@ -3,7 +3,8 @@ ## SmartStore.NET 2.5 ### New Features -* #701 Implement new export framework +* New export and import framework +* Import of customer and category data * #141 Payment and shipping methods by customer roles * #67 Restrict payment methods to countries * #94 Restrict payment methods to shipping methods @@ -28,8 +29,6 @@ * #722 System > SEO Names: Implement editing of an UrlRecord * Admin > System > System Info shows used application memory (RAM) * Added option to make VATIN mandatory during customer registration -* Customer import -* Category import ### Improvements * (Perf) Implemented static caches for URL aliases and localized properties. Increases app startup and request speed by up to 30%. From 872ac5e10049b78319fc8460586dce5113e28520 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Sun, 27 Dec 2015 12:49:19 +0100 Subject: [PATCH 117/626] Resolves #841 Activity log for deleting an order --- changelog.md | 1 + .../201512151526290_ImportFramework.cs | 5 ++ .../Setup/Builder/ActivityLogTypeMigrator.cs | 68 +++++++++++++++++++ .../SmartStore.Data/SmartStore.Data.csproj | 1 + .../Controllers/OrderController.cs | 15 +++- 5 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 src/Libraries/SmartStore.Data/Setup/Builder/ActivityLogTypeMigrator.cs diff --git a/changelog.md b/changelog.md index 3d69214836..9447f0b4da 100644 --- a/changelog.md +++ b/changelog.md @@ -29,6 +29,7 @@ * #722 System > SEO Names: Implement editing of an UrlRecord * Admin > System > System Info shows used application memory (RAM) * Added option to make VATIN mandatory during customer registration +* #841 Activity log for deleting an order ### Improvements * (Perf) Implemented static caches for URL aliases and localized properties. Increases app startup and request speed by up to 30%. diff --git a/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs b/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs index d54bff9b5c..85b09659d2 100644 --- a/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs +++ b/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs @@ -48,6 +48,7 @@ public void Seed(SmartObjectContext context) context.MigrateLocaleResources(MigrateLocaleResources); var permissionMigrator = new PermissionMigrator(context); + var activityLogMigrator = new ActivityLogTypeMigrator(context); permissionMigrator.AddPermission(new PermissionRecord { @@ -55,6 +56,8 @@ public void Seed(SmartObjectContext context) SystemName = "ManageImports", Category = "Configuration" }, new string[] { SystemCustomerRoleNames.Administrators }); + + activityLogMigrator.AddActivityLogType("DeleteOrder", "Delete order", "Auftrag gelscht"); } public void MigrateLocaleResources(LocaleResourcesBuilder builder) @@ -227,6 +230,8 @@ public void MigrateLocaleResources(LocaleResourcesBuilder builder) "Admin.Common.ImportFromExcel.DownloadReport", "Admin.Common.ImportFromExcel.NoReportAvailable" ); + + builder.AddOrUpdate("ActivityLog.DeleteOrder", "Deleted order {0}", "Auftrag {0} gelscht"); } } } diff --git a/src/Libraries/SmartStore.Data/Setup/Builder/ActivityLogTypeMigrator.cs b/src/Libraries/SmartStore.Data/Setup/Builder/ActivityLogTypeMigrator.cs new file mode 100644 index 0000000000..b397af928a --- /dev/null +++ b/src/Libraries/SmartStore.Data/Setup/Builder/ActivityLogTypeMigrator.cs @@ -0,0 +1,68 @@ +using System.Data.Entity; +using System.Linq; +using SmartStore.Core.Domain.Configuration; +using SmartStore.Core.Domain.Localization; +using SmartStore.Core.Domain.Logging; + +namespace SmartStore.Data.Setup +{ + internal class ActivityLogTypeMigrator + { + private readonly SmartObjectContext _ctx; + private readonly DbSet _activityLogTypeRecords; + + public ActivityLogTypeMigrator(SmartObjectContext ctx) + { + Guard.ArgumentNotNull(() => ctx); + + _ctx = ctx; + _activityLogTypeRecords = _ctx.Set(); + } + + private Language GetDefaultAdminLanguage(DbSet settingRecords, DbSet languageRecords) + { + const string settingKey = "LocalizationSettings.DefaultAdminLanguageId"; + + var defaultAdminLanguageSetting = settingRecords.FirstOrDefault(x => x.Name == settingKey && x.StoreId == 0); + + if (defaultAdminLanguageSetting == null) + defaultAdminLanguageSetting = settingRecords.FirstOrDefault(x => x.Name == settingKey); + + if (defaultAdminLanguageSetting != null) + { + var defaultAdminLanguageId = defaultAdminLanguageSetting.Value.ToInt(); + if (defaultAdminLanguageId != 0) + { + var language = languageRecords.FirstOrDefault(x => x.Id == defaultAdminLanguageId); + if (language != null) + return language; + } + } + + return languageRecords.First(); + } + + public void AddActivityLogType(string systemKeyword, string enName, string deName) + { + Guard.ArgumentNotEmpty(() => systemKeyword); + Guard.ArgumentNotEmpty(() => enName); + Guard.ArgumentNotEmpty(() => deName); + + var record = _activityLogTypeRecords.FirstOrDefault(x => x.SystemKeyword == systemKeyword); + + if (record == null) + { + var language = GetDefaultAdminLanguage(_ctx.Set(), _ctx.Set()); + + _activityLogTypeRecords.Add(new ActivityLogType + { + Enabled = true, + SystemKeyword = systemKeyword, + Name = (language.UniqueSeoCode.IsCaseInsensitiveEqual("de") ? deName : enName) + }); + + _ctx.SaveChanges(); + } + } + } +} diff --git a/src/Libraries/SmartStore.Data/SmartStore.Data.csproj b/src/Libraries/SmartStore.Data/SmartStore.Data.csproj index afc16698c0..951d5703c5 100644 --- a/src/Libraries/SmartStore.Data/SmartStore.Data.csproj +++ b/src/Libraries/SmartStore.Data/SmartStore.Data.csproj @@ -376,6 +376,7 @@ 201512151526290_ImportFramework.cs + diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/OrderController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/OrderController.cs index 0bdc537cac..fd82849786 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/OrderController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/OrderController.cs @@ -15,6 +15,7 @@ using SmartStore.Core.Domain.Tax; using SmartStore.Core.Events; using SmartStore.Core.Html; +using SmartStore.Core.Logging; using SmartStore.Services; using SmartStore.Services.Affiliates; using SmartStore.Services.Catalog; @@ -80,6 +81,7 @@ public partial class OrderController : AdminControllerBase private readonly ICustomerService _customerService; private readonly PluginMediator _pluginMediator; private readonly IAffiliateService _affiliateService; + private readonly ICustomerActivityService _customerActivityService; private readonly CatalogSettings _catalogSettings; private readonly CurrencySettings _currencySettings; @@ -119,7 +121,8 @@ public OrderController(IOrderService orderService, ICustomerService customerService, PluginMediator pluginMediator, IAffiliateService affiliateService, - CatalogSettings catalogSettings, CurrencySettings currencySettings, TaxSettings taxSettings, + ICustomerActivityService customerActivityService, + CatalogSettings catalogSettings, CurrencySettings currencySettings, TaxSettings taxSettings, MeasureSettings measureSettings, PdfSettings pdfSettings, AddressSettings addressSettings, IPdfConverter pdfConverter, ICommonServices services, Lazy pictureService) { @@ -156,6 +159,7 @@ public OrderController(IOrderService orderService, this._customerService = customerService; this._pluginMediator = pluginMediator; this._affiliateService = affiliateService; + this._customerActivityService = customerActivityService; this._catalogSettings = catalogSettings; this._currencySettings = currencySettings; @@ -1230,7 +1234,14 @@ public ActionResult Delete(int id) return RedirectToAction("List"); _orderProcessingService.DeleteOrder(order); - return RedirectToAction("List"); + + var msg = T("ActivityLog.DeleteOrder", order.GetOrderNumber()); + + _customerActivityService.InsertActivity("DeleteOrder", msg); + + NotifySuccess(msg); + + return RedirectToAction("List"); } public ActionResult Print(int orderId, bool pdf = false) From 843894147cc06437abd14f7f36a3246206b9c861 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Mon, 28 Dec 2015 10:41:48 +0100 Subject: [PATCH 118/626] Resolves #840 Activity Log: Have option to exclude search engine activity --- changelog.md | 3 +- .../Logging/ICustomerActivityService.cs | 33 +++++--- .../201512151526290_ImportFramework.cs | 19 ++++- .../Customers/CustomerService.cs | 5 ++ .../Customers/ICustomerService.cs | 18 +++-- .../Logging/CustomerActivityService.cs | 26 ++++-- .../Controllers/ActivityLogController.cs | 33 ++++++-- .../Infrastructure/AutoMapperStartupTask.cs | 6 +- .../Models/Logging/ActivityLogModel.cs | 4 + .../Models/Logging/ActivityLogSearchModel.cs | 11 ++- .../Views/ActivityLog/ListLogs.cshtml | 79 +++++++++++-------- .../Shared/EditorTemplates/Boolean.cshtml | 2 +- 12 files changed, 165 insertions(+), 74 deletions(-) diff --git a/changelog.md b/changelog.md index 9447f0b4da..5c0d0e40fd 100644 --- a/changelog.md +++ b/changelog.md @@ -29,6 +29,7 @@ * #722 System > SEO Names: Implement editing of an UrlRecord * Admin > System > System Info shows used application memory (RAM) * Added option to make VATIN mandatory during customer registration +* #840 Activity log: Have option to exclude search engine activity * #841 Activity log for deleting an order ### Improvements @@ -79,7 +80,7 @@ * #796 Selected specification in product filter mask is displayed with default language (not localized) * #805 Product filter is reset if 'product sorting' or 'view mode' or 'amount of displayed products per page' is changed * Hide link to a topic page if it is limited to stores -* #829 Activity Log: Searching by customer email out of function +* #829 Activity log: Searching by customer email out of function ## SmartStore.NET 2.2.2 diff --git a/src/Libraries/SmartStore.Core/Logging/ICustomerActivityService.cs b/src/Libraries/SmartStore.Core/Logging/ICustomerActivityService.cs index 0ee497d1f8..3ff8526a96 100644 --- a/src/Libraries/SmartStore.Core/Logging/ICustomerActivityService.cs +++ b/src/Libraries/SmartStore.Core/Logging/ICustomerActivityService.cs @@ -74,20 +74,27 @@ ActivityLog InsertActivity(string systemKeyword, /// Activity log void DeleteActivity(ActivityLog activityLog); - /// - /// Gets all activity log items - /// - /// Log item creation from; null to load all customers - /// Log item creation to; null to load all customers - /// Customer identifier; null to load all customers - /// Activity log type identifier - /// Page index - /// Page size + /// + /// Gets all activity log items + /// + /// Log item creation from; null to load all customers + /// Log item creation to; null to load all customers + /// Customer identifier; null to load all customers + /// Activity log type identifier + /// Page index + /// Page size /// Customer email - /// Activity log collection - IPagedList GetAllActivities(DateTime? createdOnFrom, - DateTime? createdOnTo, int? customerId, - int activityLogTypeId, int pageIndex, int pageSize, string email = null); + /// Customer system name + /// Activity log collection + IPagedList GetAllActivities( + DateTime? createdOnFrom, + DateTime? createdOnTo, + int? customerId, + int activityLogTypeId, + int pageIndex, + int pageSize, + string email = null, + bool? customerSystemAccount = null); /// /// Gets an activity log item diff --git a/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs b/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs index 85b09659d2..1f9332d58e 100644 --- a/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs +++ b/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs @@ -228,10 +228,27 @@ public void MigrateLocaleResources(LocaleResourcesBuilder builder) "Admin.Common.ImportFromExcel.Cancel", "Admin.Common.ImportFromExcel.Cancelled", "Admin.Common.ImportFromExcel.DownloadReport", - "Admin.Common.ImportFromExcel.NoReportAvailable" + "Admin.Common.ImportFromExcel.NoReportAvailable", + "Admin.Configuration.ActivityLog.ActivityLog.Fields.ActivityLogTypeColumn" ); builder.AddOrUpdate("ActivityLog.DeleteOrder", "Deleted order {0}", "Auftrag {0} gelscht"); + + builder.AddOrUpdate("Admin.System.SystemCustomerNames.SearchEngine", "Search Engine", "Suchmaschine"); + builder.AddOrUpdate("Admin.System.SystemCustomerNames.BackgroundTask", "Background Task", "Geplante Aufgabe"); + builder.AddOrUpdate("Admin.System.SystemCustomerNames.PdfConverter", "PDF Converter", "PDF-Konvertierer"); + + builder.AddOrUpdate("Admin.Configuration.ActivityLog.ActivityLog.Fields.CustomerSystemAccount", + "Customer system account", + "Kundensystemkonto", + "Filters results by customer system accounts.", + "Filtert Ergebnisse nach Kundenystemkonten."); + + builder.AddOrUpdate("Admin.Configuration.ActivityLog.ActivityLog.Fields.CustomerEmail", + "Customer Email", + "Kunden-E-Mail", + "Filters results by customer email address.", + "Filtert Ergebnisse nach E-Mail-Adresse der Kunden."); } } } diff --git a/src/Libraries/SmartStore.Services/Customers/CustomerService.cs b/src/Libraries/SmartStore.Services/Customers/CustomerService.cs index 3537ba424f..3e60ff4baa 100644 --- a/src/Libraries/SmartStore.Services/Customers/CustomerService.cs +++ b/src/Libraries/SmartStore.Services/Customers/CustomerService.cs @@ -291,6 +291,11 @@ where customerIds.Contains(c.Id) return sortedCustomers; } + public virtual IList GetSystemAccountCustomers() + { + return _customerRepository.Table.Where(x => x.IsSystemAccount).ToList(); + } + public virtual Customer GetCustomerByGuid(Guid customerGuid) { if (customerGuid == Guid.Empty) diff --git a/src/Libraries/SmartStore.Services/Customers/ICustomerService.cs b/src/Libraries/SmartStore.Services/Customers/ICustomerService.cs index ec4b470074..0f7a914a77 100644 --- a/src/Libraries/SmartStore.Services/Customers/ICustomerService.cs +++ b/src/Libraries/SmartStore.Services/Customers/ICustomerService.cs @@ -88,12 +88,18 @@ IPagedList GetOnlineCustomers(DateTime lastActivityFromUtc, /// Customers IList GetCustomersByIds(int[] customerIds); - /// - /// Gets a customer by GUID - /// - /// Customer GUID - /// A customer - Customer GetCustomerByGuid(Guid customerGuid); + /// + /// Get system account customers + /// + /// System account customers + IList GetSystemAccountCustomers(); + + /// + /// Gets a customer by GUID + /// + /// Customer GUID + /// A customer + Customer GetCustomerByGuid(Guid customerGuid); /// /// Get customer by email diff --git a/src/Libraries/SmartStore.Services/Logging/CustomerActivityService.cs b/src/Libraries/SmartStore.Services/Logging/CustomerActivityService.cs index 08d4a77083..61ba8f21ad 100644 --- a/src/Libraries/SmartStore.Services/Logging/CustomerActivityService.cs +++ b/src/Libraries/SmartStore.Services/Logging/CustomerActivityService.cs @@ -213,19 +213,33 @@ public virtual void DeleteActivity(ActivityLog activityLog) /// Page index /// Page size /// Customer email + /// Customer system name /// Activity log collection - public virtual IPagedList GetAllActivities(DateTime? createdOnFrom, - DateTime? createdOnTo, int? customerId, int activityLogTypeId, - int pageIndex, int pageSize, string email = null) + public virtual IPagedList GetAllActivities( + DateTime? createdOnFrom, + DateTime? createdOnTo, + int? customerId, + int activityLogTypeId, + int pageIndex, + int pageSize, + string email = null, + bool? customerSystemAccount = null) { var query = _activityLogRepository.Table; - if (email.HasValue()) + if (email.HasValue() || customerSystemAccount.HasValue) { + var queryCustomers = _customerRepository.Table; + + if (email.HasValue()) + queryCustomers = queryCustomers.Where(x => x.Email == email); + + if (customerSystemAccount.HasValue) + queryCustomers = queryCustomers.Where(x => x.IsSystemAccount == customerSystemAccount.Value); + query = from al in _activityLogRepository.Table - join c in _customerRepository.Table on al.CustomerId equals c.Id - where c.Email == email + join c in queryCustomers on al.CustomerId equals c.Id select al; } diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/ActivityLogController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/ActivityLogController.cs index 479b394285..e6c49b910e 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/ActivityLogController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/ActivityLogController.cs @@ -5,6 +5,7 @@ using SmartStore.Admin.Models.Logging; using SmartStore.Core.Domain.Common; using SmartStore.Core.Logging; +using SmartStore.Services.Customers; using SmartStore.Services.Helpers; using SmartStore.Services.Security; using SmartStore.Web.Framework.Controllers; @@ -20,7 +21,8 @@ public partial class ActivityLogController : AdminControllerBase #region Fields private readonly ICustomerActivityService _customerActivityService; - private readonly IDateTimeHelper _dateTimeHelper; + private readonly ICustomerService _customerService; + private readonly IDateTimeHelper _dateTimeHelper; private readonly IPermissionService _permissionService; private readonly AdminAreaSettings _adminAreaSettings; @@ -30,11 +32,13 @@ public partial class ActivityLogController : AdminControllerBase public ActivityLogController( ICustomerActivityService customerActivityService, - IDateTimeHelper dateTimeHelper, + ICustomerService customerService, + IDateTimeHelper dateTimeHelper, IPermissionService permissionService, AdminAreaSettings adminAreaSettings) { this._customerActivityService = customerActivityService; + this._customerService = customerService; this._dateTimeHelper = dateTimeHelper; this._permissionService = permissionService; this._adminAreaSettings = adminAreaSettings; @@ -132,17 +136,34 @@ public JsonResult ListActivityLogs(GridCommand command, ActivityLogSearchModel m DateTime? endDateValue = (model.CreatedOnTo == null) ? null : (DateTime?)_dateTimeHelper.ConvertToUtcTime(model.CreatedOnTo.Value, _dateTimeHelper.CurrentTimeZone).AddDays(1); - var activityLog = _customerActivityService.GetAllActivities(startDateValue, endDateValue,null, model.ActivityLogTypeId, - command.Page - 1, command.PageSize, model.CustomerEmail); + var activityLog = _customerActivityService.GetAllActivities(startDateValue, endDateValue, null, model.ActivityLogTypeId, + command.Page - 1, command.PageSize, model.CustomerEmail, model.CustomerSystemAccount); - var gridModel = new GridModel + var systemAccountCustomers = _customerService.GetSystemAccountCustomers(); + + var gridModel = new GridModel { Data = activityLog.Select(x => { var m = x.ToModel(); + var systemCustomer = systemAccountCustomers.FirstOrDefault(y => y.Id == x.CustomerId); + m.CreatedOn = _dateTimeHelper.ConvertToUserTime(x.CreatedOnUtc, DateTimeKind.Utc); + m.IsSystemAccount = (systemCustomer != null); + + if (systemCustomer != null) + { + if (systemCustomer.IsSearchEngineAccount()) + m.SystemAccountName = T("Admin.System.SystemCustomerNames.SearchEngine"); + else if (systemCustomer.IsBackgroundTaskAccount()) + m.SystemAccountName = T("Admin.System.SystemCustomerNames.BackgroundTask"); + else if (systemCustomer.IsPdfConverter()) + m.SystemAccountName = T("Admin.System.SystemCustomerNames.PdfConverter"); + else + m.SystemAccountName = "".NaIfEmpty(); + } + return m; - }), Total = activityLog.TotalCount }; diff --git a/src/Presentation/SmartStore.Web/Administration/Infrastructure/AutoMapperStartupTask.cs b/src/Presentation/SmartStore.Web/Administration/Infrastructure/AutoMapperStartupTask.cs index be8da41f25..37c9efe5ed 100644 --- a/src/Presentation/SmartStore.Web/Administration/Infrastructure/AutoMapperStartupTask.cs +++ b/src/Presentation/SmartStore.Web/Administration/Infrastructure/AutoMapperStartupTask.cs @@ -315,8 +315,10 @@ public void Execute() Mapper.CreateMap() .ForMember(dest => dest.ActivityLogTypeName, mo => mo.MapFrom(src => src.ActivityLogType.Name)) .ForMember(dest => dest.CustomerEmail, mo => mo.MapFrom(src => src.Customer.Email)) - .ForMember(dest => dest.CreatedOn, mo => mo.Ignore()); - //currencies + .ForMember(dest => dest.CreatedOn, mo => mo.Ignore()) + .ForMember(dest => dest.IsSystemAccount, mo => mo.Ignore()) + .ForMember(dest => dest.SystemAccountName, mo => mo.Ignore()); + //currencies Mapper.CreateMap() .ForMember(dest => dest.CreatedOn, mo => mo.Ignore()) .ForMember(dest => dest.IsPrimaryExchangeRateCurrency, mo => mo.Ignore()) diff --git a/src/Presentation/SmartStore.Web/Administration/Models/Logging/ActivityLogModel.cs b/src/Presentation/SmartStore.Web/Administration/Models/Logging/ActivityLogModel.cs index f686e115bb..7b5b9a57ac 100644 --- a/src/Presentation/SmartStore.Web/Administration/Models/Logging/ActivityLogModel.cs +++ b/src/Presentation/SmartStore.Web/Administration/Models/Logging/ActivityLogModel.cs @@ -20,5 +20,9 @@ public partial class ActivityLogModel : EntityModelBase [SmartResourceDisplayName("Admin.Configuration.ActivityLog.ActivityLog.Fields.CreatedOn")] public DateTime CreatedOn { get; set; } + + [SmartResourceDisplayName("Admin.Customers.Customers.Fields.IsSystemAccount")] + public bool IsSystemAccount { get; set; } + public string SystemAccountName { get; set; } } } diff --git a/src/Presentation/SmartStore.Web/Administration/Models/Logging/ActivityLogSearchModel.cs b/src/Presentation/SmartStore.Web/Administration/Models/Logging/ActivityLogSearchModel.cs index 210b7d644a..9e17c5bbcf 100644 --- a/src/Presentation/SmartStore.Web/Administration/Models/Logging/ActivityLogSearchModel.cs +++ b/src/Presentation/SmartStore.Web/Administration/Models/Logging/ActivityLogSearchModel.cs @@ -10,6 +10,10 @@ public class ActivityLogSearchModel : ModelBase { public int GridPageSize { get; set; } + [SmartResourceDisplayName("Admin.Configuration.ActivityLog.ActivityLog.Fields.ActivityLogType")] + public int ActivityLogTypeId { get; set; } + public IList ActivityLogType { get; set; } + [SmartResourceDisplayName("Admin.Configuration.ActivityLog.ActivityLog.Fields.CreatedOnFrom")] public DateTime? CreatedOnFrom { get; set; } @@ -20,8 +24,7 @@ public class ActivityLogSearchModel : ModelBase [AllowHtml] public string CustomerEmail { get; set; } - [SmartResourceDisplayName("Admin.Configuration.ActivityLog.ActivityLog.Fields.ActivityLogType")] - public int ActivityLogTypeId { get; set; } - public IList ActivityLogType { get; set; } - } + [SmartResourceDisplayName("Admin.Configuration.ActivityLog.ActivityLog.Fields.CustomerSystemAccount")] + public bool? CustomerSystemAccount { get; set; } + } } \ No newline at end of file diff --git a/src/Presentation/SmartStore.Web/Administration/Views/ActivityLog/ListLogs.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/ActivityLog/ListLogs.cshtml index bf1eb8813b..dbd3b7329e 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/ActivityLog/ListLogs.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/ActivityLog/ListLogs.cshtml @@ -23,22 +23,30 @@

@T("Admin.DataExchange.ColumnMapping.ImportField")@T("Admin.DataExchange.ColumnMapping.ImportFieldIndex")@T("Admin.DataExchange.ColumnMapping.ImportField")@T("Common.Language") @T("Admin.DataExchange.ColumnMapping.EntityProperty") @T("Admin.DataExchange.ColumnMapping.DefaultValue")
- @mapping.ColumnWithoutIndex + @if (mapping.ColumnLocalized.HasValue()) + { +
@mapping.ColumnLocalized
+ } +
@mapping.Column
- @mapping.ColumnIndex + @if (mapping.ColumnIndex.HasValue()) + { + if (mapping.LanguageDescription.HasValue()) + { + if (mapping.FlagImageFileName.HasValue()) + { + Icon + } + @mapping.LanguageDescription + } + else + { + @T("Common.Unknown") + } + } - @foreach (var prop in Model.AvailableEntityProperties) { - var select = ((mapping.EntityProperty.HasValue() && prop.Value.IsCaseInsensitiveEqual(mapping.EntityProperty)) || - (!mapping.EntityProperty.HasValue() && prop.Value.IsCaseInsensitiveEqual(mapping.Column))); + var select = !mapping.IsNilProperty && + ((mapping.Property.HasValue() && prop.Value.IsCaseInsensitiveEqual(mapping.Property)) || + (!mapping.Property.HasValue() && prop.Value.IsCaseInsensitiveEqual(mapping.ColumnWithoutIndex))); }
- @Html.ValidationMessage("ColumnMapping.EntityProperty." + mapping.Index.ToString()) + @Html.ValidationMessage("ColumnMapping.Property." + mapping.Index.ToString())
- +
  - @Html.Partial("_ImportFileList", Model) + @foreach (var fileName in Model.ExistingFileNames) + { +

+ @Html.IconForFileExtension(Path.GetExtension(fileName), false) + @fileName + + +

+ }
- - - - - - - - + + + + + + + + + + + + - - - - + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + +
- @Html.SmartLabelFor(model => model.CreatedOnFrom) - - @Html.EditorFor(model => model.CreatedOnFrom) -
- @Html.SmartLabelFor(model => model.CreatedOnTo) - - @Html.EditorFor(model => model.CreatedOnTo) -
+ @Html.SmartLabelFor(model => model.CreatedOnFrom) + + @Html.EditorFor(model => model.CreatedOnFrom) +
+ @Html.SmartLabelFor(model => model.CreatedOnTo) + + @Html.EditorFor(model => model.CreatedOnTo) +
+ @Html.SmartLabelFor(model => model.ActivityLogTypeId) + + @Html.DropDownListFor(ModelBase => ModelBase.ActivityLogTypeId, Model.ActivityLogType, T("Common.Unspecified")) +
@Html.SmartLabelFor(model => model.CustomerEmail) @@ -47,14 +55,14 @@ @Html.EditorFor(model => model.CustomerEmail)
- @Html.SmartLabelFor(model => model.ActivityLogTypeId) - - @Html.DropDownListFor(ModelBase => ModelBase.ActivityLogTypeId, Model.ActivityLogType, T("Common.Unspecified")) -
+ @Html.SmartLabelFor(model => model.CustomerSystemAccount) + + @Html.EditorFor(model => Model.CustomerSystemAccount) +
  @@ -89,12 +97,14 @@ .HtmlAttributes(new { style = "text-align:center" }) .HeaderHtmlAttributes(new { style = "text-align:center" }); columns.Bound(x => x.ActivityLogTypeName); + columns.Bound(x => x.Comment); columns.Bound(x => x.CustomerId) - .Template(x => Html.ActionLink(x.CustomerEmail, "Edit", "Customer", new { id = x.CustomerId }, new { })) .ClientTemplate("\"><#= CustomerEmail #>"); - columns.Bound(x => x.Comment); + columns.Bound(x => x.IsSystemAccount) + .ClientTemplate(" <#= SystemAccountName #>") + .Width(220); columns.Bound(x => x.CreatedOn) - .Width(180); + .Width(200); }) .DataBinding(dataBinding => { @@ -146,20 +156,20 @@ $('.checkboxGroups').attr('checked', $(this).is(':checked')).change(); }); - //wire up checkboxes. + //wire up checkboxes. $(document).on('change', '#activityLog-grid input[type=checkbox][id!=mastercheckbox]', function (e) { var $check = $(this); if ($check.is(":checked") == true) { var checked = jQuery.inArray($check.val(), selectedIds); if (checked == -1) { - //add id to selectedIds. + //add id to selectedIds. selectedIds.push($check.val()); } } else { var checked = jQuery.inArray($check.val(), selectedIds); if (checked > -1) { - //remove id from selectedIds. + //remove id from selectedIds. selectedIds = $.grep(selectedIds, function (item, index) { return item != $check.val(); }); @@ -179,11 +189,12 @@ }); function onDataBinding(e) { - var searchModel = { + var searchModel = { + ActivityLogTypeId: $('#ActivityLogTypeId').val(), CreatedOnFrom: $('#@Html.FieldIdFor(model => model.CreatedOnFrom)').val(), CreatedOnTo: $('#@Html.FieldIdFor(model => model.CreatedOnTo)').val(), - CustomerEmail: $('#@Html.FieldIdFor(model => model.CustomerEmail)').val(), - ActivityLogTypeId: $('#ActivityLogTypeId').val() + CustomerEmail: $('#@Html.FieldIdFor(model => model.CustomerEmail)').val(), + CustomerSystemAccount: $('#@Html.FieldIdFor(model => model.CustomerSystemAccount)').val() }; e.data = searchModel; } @@ -192,7 +203,7 @@ $('#activityLog-grid input[type=checkbox][id!=mastercheckbox]').each(function () { var currentId = $(this).val(); var checked = jQuery.inArray(currentId, selectedIds); - //set checked based on if current checkbox's value is in selectedIds. + //set checked based on if current checkbox's value is in selectedIds. $(this).attr('checked', checked > -1); }); diff --git a/src/Presentation/SmartStore.Web/Views/Shared/EditorTemplates/Boolean.cshtml b/src/Presentation/SmartStore.Web/Views/Shared/EditorTemplates/Boolean.cshtml index 58f0a1f824..d67441694a 100644 --- a/src/Presentation/SmartStore.Web/Views/Shared/EditorTemplates/Boolean.cshtml +++ b/src/Presentation/SmartStore.Web/Views/Shared/EditorTemplates/Boolean.cshtml @@ -18,7 +18,7 @@ get { return new List { - new SelectListItem { Text = T("Common.Undefined").ToString(), Value = String.Empty, Selected = !Value.HasValue }, + new SelectListItem { Text = T("Common.Unspecified").ToString(), Value = String.Empty, Selected = !Value.HasValue }, new SelectListItem { Text = T("Common.Yes").ToString(), Value = "true", Selected = Value.HasValue && Value.Value }, new SelectListItem { Text = T("Common.No").ToString(), Value = "false", Selected = Value.HasValue && !Value.Value }, }; From 1d520969f53c0133f0b2d5fc4dbd19275484d031 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Mon, 28 Dec 2015 12:45:36 +0100 Subject: [PATCH 119/626] Minor change --- .../DataExchange/ExportExtensions.cs | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/Libraries/SmartStore.Services/DataExchange/ExportExtensions.cs b/src/Libraries/SmartStore.Services/DataExchange/ExportExtensions.cs index a0c9f14dcc..3d65d673c8 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/ExportExtensions.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/ExportExtensions.cs @@ -128,22 +128,5 @@ public static string ResolveFileNamePattern(this ExportProfile profile, Store st return result; } - - /// - /// Join values into a string that can be used for exporting - /// - /// Type - /// Enumerable of values to join - /// Joined values - public static string JoinForExport(this IEnumerable values) - { - if (values == null) - return ""; - - if (typeof(T) == typeof(string)) - return string.Join("|", values); // because file paths cannot contain pipes - - return string.Join(",", values); - } } } From b193504387fc2ab4422bb7174632b21530519a68 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Mon, 28 Dec 2015 14:59:08 +0100 Subject: [PATCH 120/626] Added exception handling when executing child action to reach a plugin configuration page --- .../Migrations/201512151526290_ImportFramework.cs | 4 ++++ .../Views/Plugin/ConfigurePlugin.cshtml | 13 ++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs b/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs index 1f9332d58e..ce556e3c97 100644 --- a/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs +++ b/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs @@ -249,6 +249,10 @@ public void MigrateLocaleResources(LocaleResourcesBuilder builder) "Kunden-E-Mail", "Filters results by customer email address.", "Filtert Ergebnisse nach E-Mail-Adresse der Kunden."); + + builder.AddOrUpdate("Admin.Configuration.Plugins.UnknownError", + "An unknown error occurred in the configuration page of the plugin. Please refer to the following message for details.", + "Beim Aufruf der Konfigurationsseite des Plugins ist ein unbekannter Fehler aufgetreten. Details entnehmen Sie bitte der folgenden Meldung."); } } } diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Plugin/ConfigurePlugin.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Plugin/ConfigurePlugin.cshtml index 2122382080..74f552e016 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Plugin/ConfigurePlugin.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Plugin/ConfigurePlugin.cshtml @@ -20,7 +20,18 @@ @if (Model.ConfigurationRoute != null && Model.ConfigurationRoute.Action.HasValue()) { - @Html.Action(Model.ConfigurationRoute.Action, Model.ConfigurationRoute.Controller, Model.ConfigurationRoute.RouteValues); + try + { + @Html.Action(Model.ConfigurationRoute.Action, Model.ConfigurationRoute.Controller, Model.ConfigurationRoute.RouteValues); + } + catch (Exception exception) + { +
+ @T("Admin.Configuration.Plugins.UnknownError") +
+ +
@exception.ToString()
+ } } else { From 045f6cada27980b29fe7e5b3a1ae5a66bd1f6a7b Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Mon, 28 Dec 2015 16:58:48 +0100 Subject: [PATCH 121/626] Changed a string resource --- .../Migrations/201512151526290_ImportFramework.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs b/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs index ce556e3c97..fc73822866 100644 --- a/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs +++ b/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs @@ -251,8 +251,8 @@ public void MigrateLocaleResources(LocaleResourcesBuilder builder) "Filtert Ergebnisse nach E-Mail-Adresse der Kunden."); builder.AddOrUpdate("Admin.Configuration.Plugins.UnknownError", - "An unknown error occurred in the configuration page of the plugin. Please refer to the following message for details.", - "Beim Aufruf der Konfigurationsseite des Plugins ist ein unbekannter Fehler aufgetreten. Details entnehmen Sie bitte der folgenden Meldung."); + "An unknown error occurred when calling a plugin. Please refer to the following message for details.", + "Beim Aufruf eines Plugins ist ein unbekannter Fehler aufgetreten. Details entnehmen Sie bitte der folgenden Meldung."); } } } From 65de4b50f28a1e347265158206bf857cd132342a Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Mon, 28 Dec 2015 21:08:58 +0100 Subject: [PATCH 122/626] Some more changed string resources --- .../Migrations/201512151526290_ImportFramework.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs b/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs index fc73822866..df084212a5 100644 --- a/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs +++ b/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs @@ -148,7 +148,7 @@ public void MigrateLocaleResources(LocaleResourcesBuilder builder) builder.AddOrUpdate("Admin.DataExchange.Csv.Quote", "Quote character", "Anfhrungszeichen", - "Spacifies the quotation character.", + "Specifies the quotation character.", "Legt das zu verwendende Anfhrungszeichen fest."); builder.AddOrUpdate("Admin.DataExchange.Csv.Escape", @@ -197,7 +197,7 @@ public void MigrateLocaleResources(LocaleResourcesBuilder builder) builder.AddOrUpdate("Admin.Promotions.NewsLetterSubscriptions.Fields.NewsLetterSubscriptionGuid", "Subscription GUID", "Abonnement GUID"); builder.AddOrUpdate("Admin.DataExchange.ColumnMapping.Note", - "For each field of the import file you can optionally set whether and to which entity property the data is to be imported. Specifying a default value is also possible, which is applied when the import field is empty. Through Reset all made assignments are reset to their original values.", + "For each field of the import file you can optionally set whether and to which entity property the data is to be imported. It is also possible to define a default value which is applied when the import field is empty. Through Clear all made assignments are reset to their original values.", "Sie knnen optional fr jedes Feld der Importdatei festlegen, ob und nach welcher Entittseigenschaft dessen Daten importiert werden sollen. Zudem ist die Angabe eines Standardwertes mglich, der angewendet wird, wenn das Importfeld leer ist. ber Zurcksetzen werden alle gettigten Zuordnungen auf ihre Ursprungswerte zurckgesetzt."); builder.AddOrUpdate("Admin.DataExchange.ColumnMapping.ImportField", "Import Field", "Importfeld"); From 177bd689c9cca528316eabc7935c8fb83c93cb0a Mon Sep 17 00:00:00 2001 From: Murat Cakir Date: Tue, 29 Dec 2015 17:56:20 +0100 Subject: [PATCH 123/626] EnumerableConverter can also convert from intrinsic numeric types --- .../TypeConversion/EnumerableConverter.cs | 11 ++++++++++- src/Tests/SmartStore.Core.Tests/ConversionTests.cs | 5 +++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/Libraries/SmartStore.Core/ComponentModel/TypeConversion/EnumerableConverter.cs b/src/Libraries/SmartStore.Core/ComponentModel/TypeConversion/EnumerableConverter.cs index b265dbf8aa..b7120d9ede 100644 --- a/src/Libraries/SmartStore.Core/ComponentModel/TypeConversion/EnumerableConverter.cs +++ b/src/Libraries/SmartStore.Core/ComponentModel/TypeConversion/EnumerableConverter.cs @@ -78,7 +78,7 @@ private static Func, object> CreateSequenceActivator(Type sequenc public override bool CanConvertFrom(Type type) { - return type == typeof(string); + return type == typeof(string) || typeof(IConvertible).IsAssignableFrom(type); } public override bool CanConvertTo(Type type) @@ -105,6 +105,15 @@ public override object ConvertFrom(CultureInfo culture, object value) return _activator(result); } + if (value is IConvertible) + { + var result2 = (new object[] { value }) + .Select(x => Convert.ChangeType(value, typeof(T))) + .Cast(); + + return _activator(result2); + } + return base.ConvertFrom(culture, value); } diff --git a/src/Tests/SmartStore.Core.Tests/ConversionTests.cs b/src/Tests/SmartStore.Core.Tests/ConversionTests.cs index bd4dddc45c..f9a3e61f96 100644 --- a/src/Tests/SmartStore.Core.Tests/ConversionTests.cs +++ b/src/Tests/SmartStore.Core.Tests/ConversionTests.cs @@ -171,6 +171,11 @@ public void CanConvertEnumerables() var list3 = new List(new int[] { 1,2,3,4,5 }); var str = list3.Convert(); Assert.AreEqual("1,2,3,4,5", str); + + var list4 = ((double)5).Convert>(); + list4.ShouldBe>(); + Assert.AreEqual(1, list4.Count); + Assert.AreEqual(5, list4[0]); } [Test] From fc059d573c303a3429749f181437c28224ad917e Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Wed, 30 Dec 2015 11:21:38 +0100 Subject: [PATCH 124/626] Minor improvement --- .../ComponentModel/TypeConversion/EnumerableConverter.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Libraries/SmartStore.Core/ComponentModel/TypeConversion/EnumerableConverter.cs b/src/Libraries/SmartStore.Core/ComponentModel/TypeConversion/EnumerableConverter.cs index b7120d9ede..1980693205 100644 --- a/src/Libraries/SmartStore.Core/ComponentModel/TypeConversion/EnumerableConverter.cs +++ b/src/Libraries/SmartStore.Core/ComponentModel/TypeConversion/EnumerableConverter.cs @@ -146,7 +146,7 @@ protected virtual string[] GetStringArray(string input) { if (!String.IsNullOrEmpty(input)) { - var splitChar = ','; + var splitChar = '|'; if (input.IndexOf(splitChar) < 0) { @@ -154,9 +154,9 @@ protected virtual string[] GetStringArray(string input) { splitChar = ';'; } - else if (input.IndexOf('|') > -1) + else if (input.IndexOf(',') > -1) { - splitChar = '|'; + splitChar = ','; } } From dcdc59130dc7954f9865253b949d7dff59ab0f60 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Mon, 4 Jan 2016 11:20:56 +0100 Subject: [PATCH 125/626] More settings to control creation of SEO names --- changelog.md | 1 + .../SmartStore.Core/Domain/Seo/SeoSettings.cs | 62 ++++++-- .../SmartStore.Core/Utilities/SeoHelper.cs | 142 +++++++++--------- .../201508121735397_AddSyncMapping.cs | 2 +- .../201512151526290_ImportFramework.cs | 25 +++ .../SmartStore.Services/Seo/SeoExtensions.cs | 3 +- .../Controllers/SettingController.cs | 29 +++- .../Settings/GeneralCommonSettingsModel.cs | 11 +- .../Views/Setting/GeneralCommon.cshtml | 77 ++++++++-- .../Seo/SeoExtensionsTests.cs | 32 ++-- 10 files changed, 276 insertions(+), 108 deletions(-) diff --git a/changelog.md b/changelog.md index 5c0d0e40fd..ac7dd3701f 100644 --- a/changelog.md +++ b/changelog.md @@ -31,6 +31,7 @@ * Added option to make VATIN mandatory during customer registration * #840 Activity log: Have option to exclude search engine activity * #841 Activity log for deleting an order +* More settings to control creation of SEO names ### Improvements * (Perf) Implemented static caches for URL aliases and localized properties. Increases app startup and request speed by up to 30%. diff --git a/src/Libraries/SmartStore.Core/Domain/Seo/SeoSettings.cs b/src/Libraries/SmartStore.Core/Domain/Seo/SeoSettings.cs index f6ec324336..aa0b352df3 100644 --- a/src/Libraries/SmartStore.Core/Domain/Seo/SeoSettings.cs +++ b/src/Libraries/SmartStore.Core/Domain/Seo/SeoSettings.cs @@ -1,25 +1,68 @@ - +using System; using System.Collections.Generic; using SmartStore.Core.Configuration; namespace SmartStore.Core.Domain.Seo { - public class SeoSettings : ISettings + public class SeoSettings : ISettings { public SeoSettings() { PageTitleSeparator = ". "; PageTitleSeoAdjustment = PageTitleSeoAdjustment.PagenameAfterStorename; - DefaultTitle = "Your store"; + DefaultTitle = "Shop"; DefaultMetaKeywords = ""; DefaultMetaDescription = ""; - AllowUnicodeCharsInUrls = true; - CanonicalHostNameRule = Seo.CanonicalHostNameRule.NoRule; - ReservedUrlRecordSlugs = new List { "admin", "install", "recentlyviewedproducts", "newproducts", "compareproducts", "clearcomparelist", "setproductreviewhelpfulness", "login", "register", "logout", "cart", "wishlist", "emailwishlist", "checkout", "contactus", "passwordrecovery", "subscribenewsletter", "blog", "boards", "inboxupdate", "sentupdate", "news", "sitemap", "sitemapseo", "search", "config", "api", "odata" }; - ExtraRobotsDisallows = new List { "/blog/tag/", "/blog/month/", "/producttags/" }; + AllowUnicodeCharsInUrls = false; + CanonicalHostNameRule = CanonicalHostNameRule.NoRule; LoadAllUrlAliasesOnStartup = true; + + ExtraRobotsDisallows = new List { "/blog/tag/", "/blog/month/", "/producttags/" }; + + ReservedUrlRecordSlugs = new List + { + "admin", + "install", + "recentlyviewedproducts", + "newproducts", + "compareproducts", + "clearcomparelist", + "setproductreviewhelpfulness", + "login", + "register", + "logout", + "cart", + "wishlist", + "emailwishlist", + "checkout", + "contactus", + "passwordrecovery", + "subscribenewsletter", + "blog", + "boards", + "inboxupdate", + "sentupdate", + "news", + "sitemap", + "sitemapseo", + "search", + "config", + "api", + "odata" + }; + + SeoNameCharConversion = string.Join(Environment.NewLine, new List + { + "ä;ae", + "ö;oe", + "ü;ue", + "Ä;Ae", + "Ö;Oe", + "Ü;Ue", + "ß;ss" + }); } - + public string PageTitleSeparator { get; set; } public PageTitleSeoAdjustment PageTitleSeoAdjustment { get; set; } public string DefaultTitle { get; set; } @@ -28,8 +71,9 @@ public SeoSettings() public bool ConvertNonWesternChars { get; set; } public bool AllowUnicodeCharsInUrls { get; set; } + public string SeoNameCharConversion { get; set; } - public bool CanonicalUrlsEnabled { get; set; } + public bool CanonicalUrlsEnabled { get; set; } public CanonicalHostNameRule CanonicalHostNameRule { get; set; } /// diff --git a/src/Libraries/SmartStore.Core/Utilities/SeoHelper.cs b/src/Libraries/SmartStore.Core/Utilities/SeoHelper.cs index f76b247354..3dec92a6d4 100644 --- a/src/Libraries/SmartStore.Core/Utilities/SeoHelper.cs +++ b/src/Libraries/SmartStore.Core/Utilities/SeoHelper.cs @@ -1,107 +1,109 @@ using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; -using System.Linq; using System.Text; namespace SmartStore.Utilities { - + public static class SeoHelper { + private static readonly string _okChars = "abcdefghijklmnopqrstuvwxyz1234567890 _-/"; + private static readonly object _lock = new object(); private static Dictionary _seoCharacterTable; - private static readonly object s_lock = new object(); + private static Dictionary _userSeoCharacterTable; /// - /// Get SE name + /// Get SEO friendly string /// - /// Name + /// String to be converted /// A value indicating whether non western chars should be converted /// A value indicating whether Unicode chars are allowed - /// Result + /// Raw data of semicolon separated char conversions + /// SEO friendly string [SuppressMessage("ReSharper", "PossibleNullReferenceException")] - public static string GetSeName(string name, bool convertNonWesternChars, bool allowUnicodeCharsInUrls) + public static string GetSeName(string name, bool convertNonWesternChars, bool allowUnicodeCharsInUrls, string charConversions = null) { if (String.IsNullOrEmpty(name)) return name; - string okChars = "abcdefghijklmnopqrstuvwxyz1234567890 _-/"; + name = name.Trim().ToLowerInvariant(); - if (convertNonWesternChars) + if (charConversions != null && _userSeoCharacterTable == null) { - if (_seoCharacterTable == null) - InitializeSeoCharacterTable(); + InitializeUserSeoCharacterTable(charConversions); + } + + if (convertNonWesternChars && _seoCharacterTable == null) + { + InitializeSeoCharacterTable(); } var sb = new StringBuilder(); foreach (char c in name) { - string c2 = c.ToString(); - if (convertNonWesternChars) + var c2 = c.ToString(); + + if (charConversions != null && _userSeoCharacterTable != null && _userSeoCharacterTable.ContainsKey(c2)) { - if (_seoCharacterTable.ContainsKey(c2)) - c2 = _seoCharacterTable[c2]; + sb.Append(_userSeoCharacterTable[c2]); + continue; } - switch (c2) + if (convertNonWesternChars && _seoCharacterTable.ContainsKey(c2)) { - case "ä": - sb.Append("ae"); - break; - case "ö": - sb.Append("oe"); - break; - case "ü": - sb.Append("ue"); - break; - case "ß": - sb.Append("ss"); - break; - case "Ä": - sb.Append("AE"); - break; - case "Ö": - sb.Append("OE"); - break; - case "Ü": - sb.Append("UE"); - break; + c2 = _seoCharacterTable[c2]; + } - case "é": - case "è": - case "ê": - sb.Append('e'); - break; - case "á": - case "à": - case "â": - sb.Append('a'); - break; - case "ú": - case "ù": - case "û": - sb.Append('u'); - break; - case "ó": - case "ò": - case "ô": - sb.Append('o'); - break; + if (_okChars.Contains(c2) || (allowUnicodeCharsInUrls && char.IsLetterOrDigit(c))) + { + sb.Append(c2); + } + } + + sb.Replace(" ", "-"); - default: - if (okChars.Contains(c2)) - sb.Append(c2); - break; - } // switch + var result = sb.ToString(); + + while (result.Contains("--")) + { + result = result.Replace("--", "-"); } - string name2 = sb.ToString(); - name2 = name2.Replace(" ", "-"); - while (name2.Contains("--")) - name2 = name2.Replace("--", "-"); - while (name2.Contains("__")) - name2 = name2.Replace("__", "_"); + while (result.Contains("__")) + { + result = result.Replace("__", "_"); + } + return result.Trim('/'); + } + + public static void ResetUserSeoCharacterTable() + { + if (_userSeoCharacterTable != null) + { + _userSeoCharacterTable.Clear(); + _userSeoCharacterTable = null; + } + } - return name2.Trim('/'); + private static void InitializeUserSeoCharacterTable(string charConversions) + { + lock (_lock) + { + if (_userSeoCharacterTable == null) + { + _userSeoCharacterTable = new Dictionary(); + + string strLeft, strRight; + + foreach (var conversion in charConversions.SplitSafe(Environment.NewLine)) + { + if (conversion.SplitToPair(out strLeft, out strRight, ";") && strLeft.HasValue() && !_userSeoCharacterTable.ContainsKey(strLeft)) + { + _userSeoCharacterTable.Add(strLeft, strRight); + } + } + } + } } /// @@ -115,7 +117,7 @@ public static string GetSeName(string name, bool convertNonWesternChars, bool al /// private static void InitializeSeoCharacterTable() { - lock (s_lock) + lock (_lock) { if (_seoCharacterTable == null) { diff --git a/src/Libraries/SmartStore.Data/Migrations/201508121735397_AddSyncMapping.cs b/src/Libraries/SmartStore.Data/Migrations/201508121735397_AddSyncMapping.cs index b3499775ea..ce062a376e 100644 --- a/src/Libraries/SmartStore.Data/Migrations/201508121735397_AddSyncMapping.cs +++ b/src/Libraries/SmartStore.Data/Migrations/201508121735397_AddSyncMapping.cs @@ -96,7 +96,7 @@ public void MigrateLocaleResources(LocaleResourcesBuilder builder) builder.AddOrUpdate("Admin.Configuration.Settings.GeneralCommon.ExtraRobotsDisallows", "Extra Disallows for robots.txt", "Extra Disallows fr robots.txt", - "Enter additional paths that should be included as Disallow entries in your robots.txt. Each entry has to entered in a new line.", + "Enter additional paths that should be included as Disallow entries in your robots.txt. Each entry has to be entered in a new line.", "Geben Sie hier zustzliche Pfade an, die als Disallow-Eintrge zur robots.txt hinzugefgt werden sollen. Jeder Eintrag muss in einer neuen Zeile erfolgen."); builder.AddOrUpdate("Admin.Configuration.Settings.Catalog.DefaultSortOrderMode", diff --git a/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs b/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs index df084212a5..2073f9aecc 100644 --- a/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs +++ b/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs @@ -3,6 +3,7 @@ namespace SmartStore.Data.Migrations using System.Data.Entity.Migrations; using Core.Domain.Customers; using Core.Domain.Security; + using Core.Domain.Seo; using Setup; public partial class ImportFramework : DbMigration, ILocaleResourcesProvider, IDataSeeder @@ -58,6 +59,12 @@ public void Seed(SmartObjectContext context) }, new string[] { SystemCustomerRoleNames.Administrators }); activityLogMigrator.AddActivityLogType("DeleteOrder", "Delete order", "Auftrag gelscht"); + + context.MigrateSettings(x => + { + var seoSettings = new SeoSettings(); + x.Add("seosettings.seonamecharconversion", seoSettings.SeoNameCharConversion); + }); } public void MigrateLocaleResources(LocaleResourcesBuilder builder) @@ -253,6 +260,24 @@ public void MigrateLocaleResources(LocaleResourcesBuilder builder) builder.AddOrUpdate("Admin.Configuration.Plugins.UnknownError", "An unknown error occurred when calling a plugin. Please refer to the following message for details.", "Beim Aufruf eines Plugins ist ein unbekannter Fehler aufgetreten. Details entnehmen Sie bitte der folgenden Meldung."); + + builder.AddOrUpdate("Admin.Configuration.Settings.GeneralCommon.AllowUnicodeCharsInUrls", + "Allow unicode characters", + "Unicode-Zeichen erlauben", + "Check whether SEO names can contain letters that are classified as unicode characters.", + "Legt fest, ob als Unicode-Zeichen eingestufte Buchstaben in SEO relevanten Namen erlaubt sind."); + + builder.AddOrUpdate("Admin.Configuration.Settings.GeneralCommon.SeoNameCharConversion", + "Characters to be converted", + "Zu konvertierende Zeichen", + "Allows an individual conversion of characters for SEO name creation. Enter the old and the new character separated by a semicolon, e.g. ;ae. Each entry has to be entered in a new line.", + "Ermglicht das individuelle Konvertieren von Zeichen bei der Erstellung SEO Namen. Geben Sie hier durch Semikolon getrennt das alte und das neue Zeichen ein, z.B. ;ae. Jeder Eintrag muss in einer neuen Zeile erfolgen."); + + builder.AddOrUpdate("Admin.Configuration.Settings.GeneralCommon.TestSeoNameCreation", + "Check string", + "Zeichenkette prfen", + "Enter any string to check the SEO name creation. Changed settings must be saved before.", + "Geben Sie eine beliebige Zeichenkette ein, um daraus den SEO Namen zu erstellen. Genderte Einstellungen mssen zuvor gespeichert werden."); } } } diff --git a/src/Libraries/SmartStore.Services/Seo/SeoExtensions.cs b/src/Libraries/SmartStore.Services/Seo/SeoExtensions.cs index e6cc541ac4..67337bbb66 100644 --- a/src/Libraries/SmartStore.Services/Seo/SeoExtensions.cs +++ b/src/Libraries/SmartStore.Services/Seo/SeoExtensions.cs @@ -304,7 +304,8 @@ public static string GetSeName(string name, SeoSettings seoSettings) return SeoHelper.GetSeName( name, seoSettings == null ? false : seoSettings.ConvertNonWesternChars, - seoSettings == null ? false : seoSettings.AllowUnicodeCharsInUrls); + seoSettings == null ? false : seoSettings.AllowUnicodeCharsInUrls, + seoSettings == null ? null : seoSettings.SeoNameCharConversion); } #endregion diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/SettingController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/SettingController.cs index 8ad100f9ee..086be63a26 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/SettingController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/SettingController.cs @@ -31,6 +31,7 @@ using SmartStore.Services.Orders; using SmartStore.Services.Security; using SmartStore.Services.Tax; +using SmartStore.Utilities; using SmartStore.Web.Framework; using SmartStore.Web.Framework.Controllers; using SmartStore.Web.Framework.Filters; @@ -1014,6 +1015,8 @@ public ActionResult GeneralCommon() model.SeoSettings.DefaultMetaKeywords = seoSettings.DefaultMetaKeywords; model.SeoSettings.DefaultMetaDescription = seoSettings.DefaultMetaDescription; model.SeoSettings.ConvertNonWesternChars = seoSettings.ConvertNonWesternChars; + model.SeoSettings.AllowUnicodeCharsInUrls = seoSettings.AllowUnicodeCharsInUrls; + model.SeoSettings.SeoNameCharConversion = seoSettings.SeoNameCharConversion; model.SeoSettings.CanonicalUrlsEnabled = seoSettings.CanonicalUrlsEnabled; model.SeoSettings.CanonicalHostNameRule = seoSettings.CanonicalHostNameRule; model.SeoSettings.ExtraRobotsDisallows = String.Join(Environment.NewLine, seoSettings.ExtraRobotsDisallows); @@ -1187,11 +1190,15 @@ public ActionResult GeneralCommon(GeneralCommonSettingsModel model, FormCollecti //seo settings var seoSettings = _services.Settings.LoadSetting(storeScope); + var resetUserSeoCharacterTable = (seoSettings.SeoNameCharConversion != model.SeoSettings.SeoNameCharConversion); + seoSettings.PageTitleSeparator = model.SeoSettings.PageTitleSeparator; seoSettings.PageTitleSeoAdjustment = model.SeoSettings.PageTitleSeoAdjustment; seoSettings.DefaultTitle = model.SeoSettings.DefaultTitle; seoSettings.DefaultMetaKeywords = model.SeoSettings.DefaultMetaKeywords; seoSettings.DefaultMetaDescription = model.SeoSettings.DefaultMetaDescription; + seoSettings.AllowUnicodeCharsInUrls = model.SeoSettings.AllowUnicodeCharsInUrls; + seoSettings.SeoNameCharConversion = model.SeoSettings.SeoNameCharConversion; seoSettings.ConvertNonWesternChars = model.SeoSettings.ConvertNonWesternChars; seoSettings.CanonicalUrlsEnabled = model.SeoSettings.CanonicalUrlsEnabled; seoSettings.CanonicalHostNameRule = model.SeoSettings.CanonicalHostNameRule; @@ -1199,6 +1206,11 @@ public ActionResult GeneralCommon(GeneralCommonSettingsModel model, FormCollecti StoreDependingSettings.UpdateSettings(seoSettings, form, storeScope, _services.Settings); + if (resetUserSeoCharacterTable) + { + SeoHelper.ResetUserSeoCharacterTable(); + } + //security settings var securitySettings = _services.Settings.LoadSetting(storeScope); if (securitySettings.AdminAreaAllowedIpAddresses == null) @@ -1492,11 +1504,24 @@ public ActionResult ToggleFullText(GeneralCommonSettingsModel model) return RedirectToAction("GeneralCommon"); } + [HttpPost] + public ActionResult TestSeoNameCreation(GeneralCommonSettingsModel model) + { + var storeScope = this.GetActiveStoreScopeConfiguration(_services.StoreService, _services.WorkContext); + var seoSettings = _services.Settings.LoadSetting(storeScope); + // we always test against persisted settings + var result = SeoHelper.GetSeName(model.SeoSettings.TestSeoNameCreation, + seoSettings.ConvertNonWesternChars, + seoSettings.AllowUnicodeCharsInUrls, + seoSettings.SeoNameCharConversion); + + return Content(result); + } - //all settings - public ActionResult AllSettings() + //all settings + public ActionResult AllSettings() { if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageSettings)) return AccessDeniedView(); diff --git a/src/Presentation/SmartStore.Web/Administration/Models/Settings/GeneralCommonSettingsModel.cs b/src/Presentation/SmartStore.Web/Administration/Models/Settings/GeneralCommonSettingsModel.cs index db49b69053..bc1821522a 100644 --- a/src/Presentation/SmartStore.Web/Administration/Models/Settings/GeneralCommonSettingsModel.cs +++ b/src/Presentation/SmartStore.Web/Administration/Models/Settings/GeneralCommonSettingsModel.cs @@ -81,7 +81,16 @@ public partial class SeoSettingsModel [SmartResourceDisplayName("Admin.Configuration.Settings.GeneralCommon.ConvertNonWesternChars")] public bool ConvertNonWesternChars { get; set; } - [SmartResourceDisplayName("Admin.Configuration.Settings.GeneralCommon.CanonicalUrlsEnabled")] + [SmartResourceDisplayName("Admin.Configuration.Settings.GeneralCommon.AllowUnicodeCharsInUrls")] + public bool AllowUnicodeCharsInUrls { get; set; } + + [SmartResourceDisplayName("Admin.Configuration.Settings.GeneralCommon.SeoNameCharConversion")] + public string SeoNameCharConversion { get; set; } + + [SmartResourceDisplayName("Admin.Configuration.Settings.GeneralCommon.TestSeoNameCreation")] + public string TestSeoNameCreation { get; set; } + + [SmartResourceDisplayName("Admin.Configuration.Settings.GeneralCommon.CanonicalUrlsEnabled")] public bool CanonicalUrlsEnabled { get; set; } [SmartResourceDisplayName("Admin.Configuration.Settings.GeneralCommon.CanonicalHostNameRule")] diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Setting/GeneralCommon.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Setting/GeneralCommon.cshtml index 60c57ccd7f..83029516f0 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Setting/GeneralCommon.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Setting/GeneralCommon.cshtml @@ -27,8 +27,8 @@ $("#@Html.FieldIdFor(model => model.StoreInformationSettings.StoreClosed)").click(toggleStoreClosed); $("#@Html.FieldIdFor(model => model.CaptchaSettings.Enabled)").change(function () { $('#SecuritySettingTable').find('.captcha-setting').toggle($(this).is(':checked')); - }).trigger('change'); - $("#@Html.FieldIdFor(model => model.LocalizationSettings.SeoFriendlyUrlsForLanguagesEnabled)").click(toggleSeoLanguageUrls); + }).trigger('change'); + $("#@Html.FieldIdFor(model => model.LocalizationSettings.SeoFriendlyUrlsForLanguagesEnabled)").click(toggleSeoLanguageUrls); toggleStoreClosed(); toggleSeoLanguageUrls(); @@ -36,6 +36,17 @@ $("#@Html.FieldIdFor(model => model.SocialSettings.ShowSocialLinksInFooter)").change(function () { $('#SocialLinkTable').find('.social-link').toggle($(this).is(':checked')); }).trigger('change'); + + // test creation of SEO names + $('#TestSeoNameCreationButton').click(function () { + $(this).closest('form').doAjax({ + type: 'POST', + url: '@Url.Action("TestSeoNameCreation")', + callbackSuccess: function (resp) { + $('#TestSeoNameCreationResult').text(resp); + } + }); + }); }); function toggleStoreClosed() { @@ -148,15 +159,6 @@ @Html.ValidationMessageFor(model => model.SeoSettings.DefaultMetaDescription)
- @Html.SmartLabelFor(model => model.SeoSettings.ConvertNonWesternChars) - - @Html.SettingEditorFor(model => model.SeoSettings.ConvertNonWesternChars) - @Html.ValidationMessageFor(model => model.SeoSettings.ConvertNonWesternChars) -
@Html.SmartLabelFor(model => model.SeoSettings.CanonicalUrlsEnabled) @@ -185,6 +187,59 @@ @Html.ValidationMessageFor(model => model.SeoSettings.ExtraRobotsDisallows)
+
+
@T("Admin.System.SeNames")
+
+
+ @Html.SmartLabelFor(model => model.SeoSettings.ConvertNonWesternChars) + + @Html.SettingEditorFor(model => model.SeoSettings.ConvertNonWesternChars) + @Html.ValidationMessageFor(model => model.SeoSettings.ConvertNonWesternChars) +
+ @Html.SmartLabelFor(model => model.SeoSettings.AllowUnicodeCharsInUrls) + + @Html.SettingEditorFor(model => model.SeoSettings.AllowUnicodeCharsInUrls) + @Html.ValidationMessageFor(model => model.SeoSettings.AllowUnicodeCharsInUrls) +
+ @Html.SmartLabelFor(model => model.SeoSettings.SeoNameCharConversion) + + @Html.TextAreaFor(model => model.SeoSettings.SeoNameCharConversion, new { @class = "input-large", style = "height:250px" }) + @Html.ValidationMessageFor(model => model.SeoSettings.SeoNameCharConversion) +
+ @Html.SmartLabelFor(model => model.SeoSettings.TestSeoNameCreation) + + @Html.EditorFor(model => model.SeoSettings.TestSeoNameCreation) + + +
+   + +
} @helper TabSecuritySettings() diff --git a/src/Tests/SmartStore.Services.Tests/Seo/SeoExtensionsTests.cs b/src/Tests/SmartStore.Services.Tests/Seo/SeoExtensionsTests.cs index 08d600fd58..3d57edf05a 100644 --- a/src/Tests/SmartStore.Services.Tests/Seo/SeoExtensionsTests.cs +++ b/src/Tests/SmartStore.Services.Tests/Seo/SeoExtensionsTests.cs @@ -1,11 +1,11 @@ -using SmartStore.Services.Seo; -using SmartStore.Tests; +using System; using NUnit.Framework; +using SmartStore.Tests; using SmartStore.Utilities; namespace SmartStore.Services.Tests.Seo { - [TestFixture] + [TestFixture] public class SeoExtensionsTests { [Test] @@ -38,17 +38,23 @@ public void Can_convert_non_western_chars() { //german letters with diacritics SeoHelper.GetSeName("testäöü", true, false).ShouldEqual("testaou"); - SeoHelper.GetSeName("testäöü", false, false).ShouldEqual("testaeoeue"); - } + SeoHelper.GetSeName("testäöü", false, false).ShouldEqual("test"); + + var charConversions = string.Join(Environment.NewLine, new string[] { "ä;ae", "ö;oe", "ü;ue" }); + + SeoHelper.GetSeName("testäöü", false, false, charConversions).ShouldEqual("testaeoeue"); + + SeoHelper.ResetUserSeoCharacterTable(); + } - //[Test] - //public void Can_allow_unicode_chars() - //{ - // //russian letters - //SeoHelper.GetSeName("testтест", false, true).ShouldEqual("testтест"); - //SeoHelper.GetSeName("testтест", false, false).ShouldEqual("test"); - //} - } + [Test] + public void Can_allow_unicode_chars() + { + //russian letters + SeoHelper.GetSeName("testтест", false, true).ShouldEqual("testтест"); + SeoHelper.GetSeName("testтест", false, false).ShouldEqual("test"); + } + } } From 6a8e630235f9ec4e1a765c0498b898f7a6b640e3 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Mon, 4 Jan 2016 13:31:57 +0100 Subject: [PATCH 126/626] Some UI cosmetic at setting pages --- .../201506181858349_AclRecordCustomerRole.cs | 8 +- .../Administration/Content/admin.less | 46 +- .../Views/Setting/Catalog.cshtml | 510 +++++++++--------- .../Administration/Views/Setting/Forum.cshtml | 9 +- .../Views/Setting/GeneralCommon.cshtml | 29 +- .../Administration/Views/Setting/Media.cshtml | 60 +-- .../Views/Setting/RewardPoints.cshtml | 130 ++--- .../Views/Setting/Shipping.cshtml | 11 +- .../Views/Setting/ShoppingCart.cshtml | 13 +- .../Administration/Views/Setting/Tax.cshtml | 29 +- 10 files changed, 428 insertions(+), 417 deletions(-) diff --git a/src/Libraries/SmartStore.Data/Migrations/201506181858349_AclRecordCustomerRole.cs b/src/Libraries/SmartStore.Data/Migrations/201506181858349_AclRecordCustomerRole.cs index c25739afec..655737641f 100644 --- a/src/Libraries/SmartStore.Data/Migrations/201506181858349_AclRecordCustomerRole.cs +++ b/src/Libraries/SmartStore.Data/Migrations/201506181858349_AclRecordCustomerRole.cs @@ -124,19 +124,19 @@ before you can assign them to all subcategories and products.
"Show manufacturers on homepage", "Zeige Hersteller auf der Homepage", "Specifies whether manufacturers will be displayed on the homepage.", - "Bestimmt ob Hersteller auf der Homepage angezeigt werden."); + "Legt fest, ob Hersteller auf der Homepage angezeigt werden."); builder.AddOrUpdate("Admin.Configuration.Settings.Catalog.ShowManufacturerPictures", "Show manufacturer pictures on homepage", "Zeige Herstellerbilder auf der Homepage", "Specifies whether manufacturers will be displayed as images or textual links on the homepage.", - "Bestimmt ob Hersteller auf der Homepage als Bilder oder textuelle Links angezeigt werden."); + "Legt fest, ob Hersteller auf der Homepage als Bilder oder textuelle Links angezeigt werden."); builder.AddOrUpdate("Admin.Configuration.Settings.CustomerUser.CustomerNumberEnabled", "Customers can enter a customer number", "Kunden knnen Kundennummer hinterlegen", "Specifies whether customers can enter a customer number.", - "Bestimmt ob Kunden eine Kundennummer hinterlegen knnen."); + "Legt fest, ob Kunden eine Kundennummer hinterlegen knnen."); builder.AddOrUpdate("Account.Fields.CustomerNumber", "Customer number", @@ -146,7 +146,7 @@ before you can assign them to all subcategories and products.
"Customers must enter a VATIN", "Kunden mssen eine Steuernummer angeben", "Specifies whether Customers must enter a VAT identification number.", - "Bestimmt ob Kunden bei der Registrierung eine Steuernummer angeben mssen."); + "Legt fest, ob Kunden bei der Registrierung eine Steuernummer angeben mssen."); builder.AddOrUpdate("Account.Fields.Vat.Required", "Please enter your VATIN", diff --git a/src/Presentation/SmartStore.Web/Administration/Content/admin.less b/src/Presentation/SmartStore.Web/Administration/Content/admin.less index a27117a25a..eff6584861 100644 --- a/src/Presentation/SmartStore.Web/Administration/Content/admin.less +++ b/src/Presentation/SmartStore.Web/Administration/Content/admin.less @@ -395,26 +395,33 @@ td.adminData > input[type="checkbox"] { .admin-config-group { .title, - .small-title { + .small-title, + .head { font-family: @headingsFontFamily; font-weight: @headingsFontWeight; color: inherit; border-bottom: 1px solid #ddd; } - .title { + .sub-title { + font-family: @baseFontFamily; + font-size: @baseFontSize; + font-weight: normal; + } + .title, + .head { font-size: @fontSizeLarge; - margin: 12px 0; padding: 8px 0; } + .head { + margin-bottom: 12px; + } + .title { + margin: 12px 0; + } .small-title { margin: 2px 0; padding: 2px 0; } - .sub-title { - font-family: @baseFontFamily; - font-size: @baseFontSize; - font-weight: normal; - } } @@ -809,6 +816,16 @@ td.adminTitle > .ctl-label { } } } +tr.adminGroup { + > td { + padding-top: 18px; + } + + label { + padding-bottom: 3px; + text-decoration: underline; + } +} td.adminTitle:hover a.hint { .opacity(100); @@ -850,13 +867,14 @@ td.adminData .t-combobox { width: 306px; } -tr.adminSeparator hr { - background-color: #D3D3D3; - border: medium none; - color: #D3D3D3; +tr.adminSeparator hr, +td.adminSeparator hr { + border: medium none; + background-color: #ddd; + color: #ddd; height: 1px; - margin-top: 10px; - margin-bottom: 10px; + margin-top: 12px; + margin-bottom: 12px; padding: 0; } diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Setting/Catalog.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Setting/Catalog.cshtml index 3e8d9e4a19..48dbb84b82 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Setting/Catalog.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Setting/Catalog.cshtml @@ -257,8 +257,7 @@ @Html.ValidationMessageFor(model => model.IgnoreFeaturedProducts)
@Html.SmartLabelFor(model => model.CompareProductsEnabled)
@Html.SmartLabelFor(model => model.EnableHtmlTextCollapser) @@ -365,257 +363,272 @@ @helper TabProductListSettings() { -
- @T("Common.Navigation") - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
- @Html.SmartLabelFor(model => model.ShowProductsFromSubcategories) - - @Html.SettingEditorFor(model => model.ShowProductsFromSubcategories) - @Html.ValidationMessageFor(model => model.ShowProductsFromSubcategories) -
- @Html.SmartLabelFor(model => model.IncludeFeaturedProductsInNormalLists) - - @Html.SettingEditorFor(model => model.IncludeFeaturedProductsInNormalLists) - @Html.ValidationMessageFor(model => model.IncludeFeaturedProductsInNormalLists) -
- @Html.SmartLabelFor(model => model.ShowCategoryProductNumber) - - @Html.SettingEditorFor(model => model.ShowCategoryProductNumber) - @Html.ValidationMessageFor(model => model.ShowCategoryProductNumber) -
- @Html.SmartLabelFor(model => model.ShowCategoryProductNumberIncludingSubcategories) - - @Html.SettingEditorFor(model => model.ShowCategoryProductNumberIncludingSubcategories) - @Html.ValidationMessageFor(model => model.ShowCategoryProductNumberIncludingSubcategories) -
- @Html.SmartLabelFor(model => model.CategoryBreadcrumbEnabled) - - @Html.SettingEditorFor(model => model.CategoryBreadcrumbEnabled) - @Html.ValidationMessageFor(model => model.CategoryBreadcrumbEnabled) -
- @Html.SmartLabelFor(model => model.FilterEnabled) - - @Html.SettingEditorFor(model => model.FilterEnabled) - @Html.ValidationMessageFor(model => model.FilterEnabled) -
- @Html.SmartLabelFor(model => model.MaxFilterItemsToDisplay) - - @Html.SettingEditorFor(model => model.MaxFilterItemsToDisplay) - @Html.ValidationMessageFor(model => model.MaxFilterItemsToDisplay) -
- @Html.SmartLabelFor(model => model.ExpandAllFilterCriteria) - - @Html.SettingEditorFor(model => model.ExpandAllFilterCriteria) - @Html.ValidationMessageFor(model => model.ExpandAllFilterCriteria) -
+ + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + -
+
+
@T("Common.Navigation")
+
+
+ @Html.SmartLabelFor(model => model.ShowProductsFromSubcategories) + + @Html.SettingEditorFor(model => model.ShowProductsFromSubcategories) + @Html.ValidationMessageFor(model => model.ShowProductsFromSubcategories) +
+ @Html.SmartLabelFor(model => model.IncludeFeaturedProductsInNormalLists) + + @Html.SettingEditorFor(model => model.IncludeFeaturedProductsInNormalLists) + @Html.ValidationMessageFor(model => model.IncludeFeaturedProductsInNormalLists) +
+ @Html.SmartLabelFor(model => model.ShowCategoryProductNumber) + + @Html.SettingEditorFor(model => model.ShowCategoryProductNumber) + @Html.ValidationMessageFor(model => model.ShowCategoryProductNumber) +
+ @Html.SmartLabelFor(model => model.ShowCategoryProductNumberIncludingSubcategories) + + @Html.SettingEditorFor(model => model.ShowCategoryProductNumberIncludingSubcategories) + @Html.ValidationMessageFor(model => model.ShowCategoryProductNumberIncludingSubcategories) +
+ @Html.SmartLabelFor(model => model.CategoryBreadcrumbEnabled) + + @Html.SettingEditorFor(model => model.CategoryBreadcrumbEnabled) + @Html.ValidationMessageFor(model => model.CategoryBreadcrumbEnabled) +
- @Html.SmartLabelFor(model => model.SubCategoryDisplayType) - - @Html.SettingOverrideCheckbox(model => Model.SubCategoryDisplayType) - @Html.DropDownListFor(model => model.SubCategoryDisplayType, Model.AvailableSubCategoryDisplayTypes) - @Html.ValidationMessageFor(model => model.SubCategoryDisplayType) -
+ @Html.SmartLabelFor(model => model.FilterEnabled) + + @Html.SettingEditorFor(model => model.FilterEnabled) + @Html.ValidationMessageFor(model => model.FilterEnabled) +
+ @Html.SmartLabelFor(model => model.MaxFilterItemsToDisplay) + + @Html.SettingEditorFor(model => model.MaxFilterItemsToDisplay) + @Html.ValidationMessageFor(model => model.MaxFilterItemsToDisplay) +
+ @Html.SmartLabelFor(model => model.ExpandAllFilterCriteria) + + @Html.SettingEditorFor(model => model.ExpandAllFilterCriteria) + @Html.ValidationMessageFor(model => model.ExpandAllFilterCriteria) +
-
+
+ @Html.SmartLabelFor(model => model.SubCategoryDisplayType) + + @Html.SettingOverrideCheckbox(model => Model.SubCategoryDisplayType) + @Html.DropDownListFor(model => model.SubCategoryDisplayType, Model.AvailableSubCategoryDisplayTypes) + @Html.ValidationMessageFor(model => model.SubCategoryDisplayType) +
-
- @T("Common.List") - - - - - - - - - - - - - - - - - - - - - - - - - -
- @Html.SmartLabelFor(model => model.AllowProductSorting) - - @Html.SettingEditorFor(model => model.AllowProductSorting) - @Html.ValidationMessageFor(model => model.AllowProductSorting) -
- @Html.SmartLabelFor(model => model.DefaultViewMode) - - @Html.SettingOverrideCheckbox(model => Model.DefaultViewMode) - @Html.DropDownListFor(model => model.DefaultViewMode, Model.AvailableDefaultViewModes) - @Html.ValidationMessageFor(model => model.DefaultViewMode) -
- @Html.SmartLabelFor(model => model.DefaultSortOrder) - - @Html.SettingOverrideCheckbox(model => Model.DefaultSortOrder) - @Html.DropDownListFor(model => model.DefaultSortOrder, Model.AvailableSortOrderModes) - @Html.ValidationMessageFor(model => model.DefaultSortOrder) -
- @Html.SmartLabelFor(model => model.AllowProductViewModeChanging) - - @Html.SettingEditorFor(model => model.AllowProductViewModeChanging) - @Html.ValidationMessageFor(model => model.AllowProductViewModeChanging) -
- @Html.SmartLabelFor(model => model.DefaultPageSizeOptions) - - @Html.SettingEditorFor(model => model.DefaultPageSizeOptions) - @Html.ValidationMessageFor(model => model.DefaultPageSizeOptions) -
- @Html.SmartLabelFor(model => model.PriceDisplayType) - - @Html.SettingOverrideCheckbox(model => Model.PriceDisplayType) - @Html.DropDownListFor(model => model.PriceDisplayType, Model.AvailablePriceDisplayTypes) - @Html.ValidationMessageFor(model => model.PriceDisplayType) -
-
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
@T("Common.List")
+
+
+ @Html.SmartLabelFor(model => model.AllowProductSorting) + + @Html.SettingEditorFor(model => model.AllowProductSorting) + @Html.ValidationMessageFor(model => model.AllowProductSorting) +
+ @Html.SmartLabelFor(model => model.DefaultViewMode) + + @Html.SettingOverrideCheckbox(model => Model.DefaultViewMode) + @Html.DropDownListFor(model => model.DefaultViewMode, Model.AvailableDefaultViewModes) + @Html.ValidationMessageFor(model => model.DefaultViewMode) +
+ @Html.SmartLabelFor(model => model.DefaultSortOrder) + + @Html.SettingOverrideCheckbox(model => Model.DefaultSortOrder) + @Html.DropDownListFor(model => model.DefaultSortOrder, Model.AvailableSortOrderModes) + @Html.ValidationMessageFor(model => model.DefaultSortOrder) +
+ @Html.SmartLabelFor(model => model.AllowProductViewModeChanging) + + @Html.SettingEditorFor(model => model.AllowProductViewModeChanging) + @Html.ValidationMessageFor(model => model.AllowProductViewModeChanging) +
+ @Html.SmartLabelFor(model => model.DefaultPageSizeOptions) + + @Html.SettingEditorFor(model => model.DefaultPageSizeOptions) + @Html.ValidationMessageFor(model => model.DefaultPageSizeOptions) +
+ @Html.SmartLabelFor(model => model.PriceDisplayType) + + @Html.SettingOverrideCheckbox(model => Model.PriceDisplayType) + @Html.DropDownListFor(model => model.PriceDisplayType, Model.AvailablePriceDisplayTypes) + @Html.ValidationMessageFor(model => model.PriceDisplayType) +
-
- @T("Admin.Catalog.Products") - - - - - - - - - - - - - - - - - - - - - -
- @Html.SmartLabelFor(model => model.ShowDeliveryTimesInProductLists) - - @Html.SettingEditorFor(model => model.ShowDeliveryTimesInProductLists) - @Html.ValidationMessageFor(model => model.ShowDeliveryTimesInProductLists) -
- @Html.SmartLabelFor(model => model.ShowBasePriceInProductLists) - - @Html.SettingEditorFor(model => model.ShowBasePriceInProductLists) - @Html.ValidationMessageFor(model => model.ShowBasePriceInProductLists) -
- @Html.SmartLabelFor(model => model.ShowColorSquaresInLists) - - @Html.SettingEditorFor(model => model.ShowColorSquaresInLists) - @Html.ValidationMessageFor(model => model.ShowColorSquaresInLists) -
- @Html.SmartLabelFor(model => model.HideBuyButtonInLists) - - @Html.SettingEditorFor(model => model.HideBuyButtonInLists) - @Html.ValidationMessageFor(model => model.HideBuyButtonInLists) -
- @Html.SmartLabelFor(model => model.LabelAsNewForMaxDays) - - @Html.SettingEditorFor(model => model.LabelAsNewForMaxDays) - @Html.ValidationMessageFor(model => model.LabelAsNewForMaxDays) -
-
+ + + + + + + + + + + + + + + + + + + + + + + + +
+
+
@T("Admin.Catalog.Products")
+
+
+ @Html.SmartLabelFor(model => model.ShowDeliveryTimesInProductLists) + + @Html.SettingEditorFor(model => model.ShowDeliveryTimesInProductLists) + @Html.ValidationMessageFor(model => model.ShowDeliveryTimesInProductLists) +
+ @Html.SmartLabelFor(model => model.ShowBasePriceInProductLists) + + @Html.SettingEditorFor(model => model.ShowBasePriceInProductLists) + @Html.ValidationMessageFor(model => model.ShowBasePriceInProductLists) +
+ @Html.SmartLabelFor(model => model.ShowColorSquaresInLists) + + @Html.SettingEditorFor(model => model.ShowColorSquaresInLists) + @Html.ValidationMessageFor(model => model.ShowColorSquaresInLists) +
+ @Html.SmartLabelFor(model => model.HideBuyButtonInLists) + + @Html.SettingEditorFor(model => model.HideBuyButtonInLists) + @Html.ValidationMessageFor(model => model.HideBuyButtonInLists) +
+ @Html.SmartLabelFor(model => model.LabelAsNewForMaxDays) + + @Html.SettingEditorFor(model => model.LabelAsNewForMaxDays) + @Html.ValidationMessageFor(model => model.LabelAsNewForMaxDays) +
-
- @T("Admin.Catalog.ProductTags") - - - - - - - - - - - - - - - - - -
- @Html.SmartLabelFor(model => model.NumberOfProductTags) - - @Html.SettingEditorFor(model => model.NumberOfProductTags) - @Html.ValidationMessageFor(model => model.NumberOfProductTags) -
- @Html.SmartLabelFor(model => model.ProductsByTagPageSize) - - @Html.SettingEditorFor(model => model.ProductsByTagPageSize) - @Html.ValidationMessageFor(model => model.ProductsByTagPageSize) -
- @Html.SmartLabelFor(model => model.ProductsByTagAllowCustomersToSelectPageSize) - - @Html.SettingEditorFor(model => model.ProductsByTagAllowCustomersToSelectPageSize) - @Html.ValidationMessageFor(model => model.ProductsByTagAllowCustomersToSelectPageSize) -
- @Html.SmartLabelFor(model => model.ProductsByTagPageSizeOptions) - - @Html.SettingEditorFor(model => model.ProductsByTagPageSizeOptions) - @Html.ValidationMessageFor(model => model.ProductsByTagPageSizeOptions) -
-
+ + + + + + + + + + + + + + + + + + + + +
+
+
@T("Admin.Catalog.ProductTags")
+
+
+ @Html.SmartLabelFor(model => model.NumberOfProductTags) + + @Html.SettingEditorFor(model => model.NumberOfProductTags) + @Html.ValidationMessageFor(model => model.NumberOfProductTags) +
+ @Html.SmartLabelFor(model => model.ProductsByTagPageSize) + + @Html.SettingEditorFor(model => model.ProductsByTagPageSize) + @Html.ValidationMessageFor(model => model.ProductsByTagPageSize) +
+ @Html.SmartLabelFor(model => model.ProductsByTagAllowCustomersToSelectPageSize) + + @Html.SettingEditorFor(model => model.ProductsByTagAllowCustomersToSelectPageSize) + @Html.ValidationMessageFor(model => model.ProductsByTagAllowCustomersToSelectPageSize) +
+ @Html.SmartLabelFor(model => model.ProductsByTagPageSizeOptions) + + @Html.SettingEditorFor(model => model.ProductsByTagPageSizeOptions) + @Html.ValidationMessageFor(model => model.ProductsByTagPageSizeOptions) +
} @helper TabUserSettings() { - +
+ + +
@Html.SmartLabelFor(model => model.ShowProductReviewsInProductLists) @@ -693,7 +706,7 @@ @helper TabProductDetailSettings() { - +
- + - + -
@Html.SmartLabelFor(model => model.RecentlyViewedProductsEnabled) @@ -834,8 +847,7 @@ } @helper TabProductSearchSettings() { - - +
- diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Setting/Forum.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Setting/Forum.cshtml index b89e7f267a..960758edfd 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Setting/Forum.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Setting/Forum.cshtml @@ -1,7 +1,6 @@ @model ForumSettingsModel @using Telerik.Web.Mvc.UI; @{ - //page title ViewBag.Title = T("Admin.Configuration.Settings.Forums").Text; } @using (Html.BeginForm()) @@ -136,8 +135,8 @@ @Html.ValidationMessageFor(model => model.SignaturesEnabled) - - + @@ -169,8 +168,8 @@ @Html.ValidationMessageFor(model => model.NotifyAboutPrivateMessages) - - + diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Setting/GeneralCommon.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Setting/GeneralCommon.cshtml index 83029516f0..517e7cc211 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Setting/GeneralCommon.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Setting/GeneralCommon.cshtml @@ -424,7 +424,7 @@ - @@ -520,9 +520,9 @@ - + - + - - -
@Html.SmartLabelFor(model => model.SearchPageProductsPerPage) @@ -873,7 +885,7 @@
+
+

+

+
-
-
+
+
@@ -638,9 +638,9 @@
-
-
+
+
@@ -669,9 +669,6 @@ @Html.ValidationMessageFor(model => model.CompanyInformationSettings.TaxNumber)
} @@ -716,9 +713,9 @@
-
-
+
+
@@ -757,9 +754,9 @@
-
-
+
+
diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Setting/Media.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Setting/Media.cshtml index 566f49c981..bc9c1fcc46 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Setting/Media.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Setting/Media.cshtml @@ -1,7 +1,6 @@ @model MediaSettingsModel @using Telerik.Web.Mvc.UI; @{ - //page title ViewBag.Title = T("Admin.Configuration.Settings.Media").Text; } @using (Html.BeginForm()) @@ -162,38 +161,31 @@ @Html.ValidationMessageFor(model => model.MaximumImageSize)
- -
- @T("Admin.Configuration.Settings.Media.PicturesStoredIntoDatabase") -
-
- @T("Admin.Configuration.Settings.Media.MovePicturesNote") -
+
+
+
@T("Admin.Configuration.Settings.Media.PicturesStoredIntoDatabase")
+
+
+ @T("Admin.Configuration.Settings.Media.MovePicturesNote") +
+ + @T(Model.PicturesStoredIntoDatabase ? "Admin.Configuration.Settings.Media.PicturesStoredIntoDatabase.Database" : "Admin.Configuration.Settings.Media.PicturesStoredIntoDatabase.FileSystem") + - - @if (Model.PicturesStoredIntoDatabase) - { - @T("Admin.Configuration.Settings.Media.PicturesStoredIntoDatabase.Database") - } - else - { - @T("Admin.Configuration.Settings.Media.PicturesStoredIntoDatabase.FileSystem") - } - - - - - + +
} \ No newline at end of file diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Setting/RewardPoints.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Setting/RewardPoints.cshtml index c6bf2240dd..769a844e41 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Setting/RewardPoints.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Setting/RewardPoints.cshtml @@ -2,7 +2,6 @@ @using Telerik.Web.Mvc.UI; @using SmartStore.Core.Domain.Orders; @{ - //page title ViewBag.Title = T("Admin.Configuration.Settings.RewardPoints").Text; } @using (Html.BeginForm()) @@ -48,67 +47,70 @@
-
- @T("Admin.Configuration.Settings.RewardPoints.Earning") - - - - - - - - - - - - - - - - - - - - - - -
- @Html.SmartLabelFor(model => model.PointsForRegistration) - - @Html.SettingOverrideCheckbox(model => Model.PointsForRegistration) - @Html.EditorFor(model => model.PointsForRegistration, new { Small = true }) - @Html.ValidationMessageFor(model => model.PointsForRegistration) -
- @Html.SmartLabelFor(model => model.PointsForProductReview) - - @Html.SettingOverrideCheckbox(model => Model.PointsForProductReview) - @Html.EditorFor(model => model.PointsForProductReview, new { Small = true }) - @Html.ValidationMessageFor(model => model.PointsForProductReview) -
- @Html.SmartLabelFor(model => model.PointsForPurchases_Amount) - - @Html.SettingOverrideCheckbox(model => Model.PointsForPurchases_OverrideForStore, "#pnlPointsForPurchases") - @T("Admin.Configuration.Settings.RewardPoints.Earning.Hint1") - @Html.EditorFor(model => model.PointsForPurchases_Amount, new { Small = true }) - @Model.PrimaryStoreCurrencyCode -   - @T("Admin.Configuration.Settings.RewardPoints.Earning.Hint2") - @Html.EditorFor(model => model.PointsForPurchases_Points, new { Small = true }) - @T("Admin.Configuration.Settings.RewardPoints.Earning.Hint3") - @Html.ValidationMessageFor(model => model.PointsForPurchases_Amount) - @Html.ValidationMessageFor(model => model.PointsForPurchases_Points) -
- @Html.SmartLabelFor(model => model.PointsForPurchases_Awarded) - - @Html.SettingOverrideCheckbox(model => Model.PointsForPurchases_Awarded) - @Html.DropDownListFor(model => model.PointsForPurchases_Awarded, ((OrderStatus)Model.PointsForPurchases_Awarded).ToSelectList()) - @Html.ValidationMessageFor(model => model.PointsForPurchases_Awarded) -
- @Html.SmartLabelFor(model => model.PointsForPurchases_Canceled) - - @Html.SettingOverrideCheckbox(model => Model.PointsForPurchases_Canceled) - @Html.DropDownListFor(model => model.PointsForPurchases_Canceled, ((OrderStatus)Model.PointsForPurchases_Canceled).ToSelectList()) - @Html.ValidationMessageFor(model => model.PointsForPurchases_Canceled) -
-
+ + + + + + + + + + + + + + + + + + + + + + + + +
+
+
@T("Admin.Configuration.Settings.RewardPoints.Earning")
+
+
+ @Html.SmartLabelFor(model => model.PointsForRegistration) + + @Html.SettingOverrideCheckbox(model => Model.PointsForRegistration) + @Html.EditorFor(model => model.PointsForRegistration, new { Small = true }) + @Html.ValidationMessageFor(model => model.PointsForRegistration) +
+ @Html.SmartLabelFor(model => model.PointsForProductReview) + + @Html.SettingOverrideCheckbox(model => Model.PointsForProductReview) + @Html.EditorFor(model => model.PointsForProductReview, new { Small = true }) + @Html.ValidationMessageFor(model => model.PointsForProductReview) +
+ @Html.SmartLabelFor(model => model.PointsForPurchases_Amount) + + @Html.SettingOverrideCheckbox(model => Model.PointsForPurchases_OverrideForStore, "#pnlPointsForPurchases") + @T("Admin.Configuration.Settings.RewardPoints.Earning.Hint1") + @Html.EditorFor(model => model.PointsForPurchases_Amount, new { Small = true }) + @Model.PrimaryStoreCurrencyCode +   + @T("Admin.Configuration.Settings.RewardPoints.Earning.Hint2") + @Html.EditorFor(model => model.PointsForPurchases_Points, new { Small = true }) + @T("Admin.Configuration.Settings.RewardPoints.Earning.Hint3") + @Html.ValidationMessageFor(model => model.PointsForPurchases_Amount) + @Html.ValidationMessageFor(model => model.PointsForPurchases_Points) +
+ @Html.SmartLabelFor(model => model.PointsForPurchases_Awarded) + + @Html.SettingOverrideCheckbox(model => Model.PointsForPurchases_Awarded) + @Html.DropDownListFor(model => model.PointsForPurchases_Awarded, ((OrderStatus)Model.PointsForPurchases_Awarded).ToSelectList()) + @Html.ValidationMessageFor(model => model.PointsForPurchases_Awarded) +
+ @Html.SmartLabelFor(model => model.PointsForPurchases_Canceled) + + @Html.SettingOverrideCheckbox(model => Model.PointsForPurchases_Canceled) + @Html.DropDownListFor(model => model.PointsForPurchases_Canceled, ((OrderStatus)Model.PointsForPurchases_Canceled).ToSelectList()) + @Html.ValidationMessageFor(model => model.PointsForPurchases_Canceled) +
} \ No newline at end of file diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Setting/Shipping.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Setting/Shipping.cshtml index 56a5139003..65f9355676 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Setting/Shipping.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Setting/Shipping.cshtml @@ -1,6 +1,5 @@ @model ShippingSettingsModel @{ - //page title ViewBag.Title = T("Admin.Configuration.Settings.Shipping").Text; } @using (Html.BeginForm()) @@ -82,14 +81,14 @@ @Html.ValidationMessageFor(model => model.DisplayShipmentEventsToCustomers) - - - @Html.LabelFor(model => model.ShippingOriginAddress, new { style="font-weight: bold" }) - + + + @Html.SmartLabelFor(model => model.ShippingOriginAddress) + @Html.SettingOverrideCheckbox(model => Model.ShippingOriginAddress, "#pnlShippingOriginAddress") - + @Html.EditorFor(model => model.ShippingOriginAddress, "Address") diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Setting/ShoppingCart.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Setting/ShoppingCart.cshtml index 2a4d51b0b4..34f62d4c96 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Setting/ShoppingCart.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Setting/ShoppingCart.cshtml @@ -1,6 +1,5 @@ @model ShoppingCartSettingsModel @{ - //page title ViewBag.Title = T("Admin.Configuration.Settings.ShoppingCart").Text; } @using (Html.BeginForm()) @@ -142,8 +141,8 @@ - - + +
@@ -176,10 +175,10 @@ - - -
- + + +
+ diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Setting/Tax.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Setting/Tax.cshtml index 150886779f..7f2e872994 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Setting/Tax.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Setting/Tax.cshtml @@ -1,7 +1,6 @@ @model TaxSettingsModel @using Telerik.Web.Mvc.UI; @{ - //page title ViewBag.Title = T("Admin.Configuration.Settings.Tax").Text; } @using (Html.BeginForm()) @@ -150,11 +149,6 @@ @Html.ValidationMessageFor(model => model.HideTaxInOrderSummary) - - -
- - @Html.SmartLabelFor(model => model.ShowLegalHintsInProductList) @@ -182,8 +176,8 @@ @Html.ValidationMessageFor(model => model.ShowLegalHintsInFooter) - - + +
@@ -197,21 +191,21 @@ @Html.ValidationMessageFor(model => model.TaxBasedOn) - + - @Html.LabelFor(model => model.DefaultTaxAddress, new { style="font-weight: bold" }) + @Html.SmartLabelFor(model => model.DefaultTaxAddress) @Html.SettingOverrideCheckbox(model => Model.DefaultTaxAddress, "#pnlDefaultTaxAddress") - + @Html.EditorFor(x => x.DefaultTaxAddress, "Address") - - + +
@@ -243,8 +237,8 @@ @Html.ValidationMessageFor(model => model.ShippingTaxClassId) - - + +
@@ -276,8 +270,8 @@ @Html.ValidationMessageFor(model => model.PaymentMethodAdditionalFeeTaxClassId) - - + +
@@ -336,6 +330,5 @@ @Html.ValidationMessageFor(model => model.VatRequired) - } \ No newline at end of file From dd74f1328433631b91676934691606822164a58a Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Mon, 4 Jan 2016 17:09:19 +0100 Subject: [PATCH 127/626] Permission list: Added label with permission category --- .../201506181858349_AclRecordCustomerRole.cs | 8 +-- .../201512151526290_ImportFramework.cs | 17 +++++ .../Security/PermissionService.cs | 16 +++-- .../Controllers/SecurityController.cs | 71 ++++++++++--------- .../Models/Security/PermissionRecordModel.cs | 22 +++++- .../Views/Security/Permissions.cshtml | 26 ++++--- 6 files changed, 105 insertions(+), 55 deletions(-) diff --git a/src/Libraries/SmartStore.Data/Migrations/201506181858349_AclRecordCustomerRole.cs b/src/Libraries/SmartStore.Data/Migrations/201506181858349_AclRecordCustomerRole.cs index 655737641f..d8c20d54d3 100644 --- a/src/Libraries/SmartStore.Data/Migrations/201506181858349_AclRecordCustomerRole.cs +++ b/src/Libraries/SmartStore.Data/Migrations/201506181858349_AclRecordCustomerRole.cs @@ -123,13 +123,13 @@ before you can assign them to all subcategories and products.
builder.AddOrUpdate("Admin.Configuration.Settings.Catalog.ShowManufacturersOnHomepage", "Show manufacturers on homepage", "Zeige Hersteller auf der Homepage", - "Specifies whether manufacturers will be displayed on the homepage.", + "Specifies whether manufacturers are displayed on the homepage.", "Legt fest, ob Hersteller auf der Homepage angezeigt werden."); builder.AddOrUpdate("Admin.Configuration.Settings.Catalog.ShowManufacturerPictures", "Show manufacturer pictures on homepage", "Zeige Herstellerbilder auf der Homepage", - "Specifies whether manufacturers will be displayed as images or textual links on the homepage.", + "Specifies whether manufacturers are displayed as images or textual links on the homepage.", "Legt fest, ob Hersteller auf der Homepage als Bilder oder textuelle Links angezeigt werden."); builder.AddOrUpdate("Admin.Configuration.Settings.CustomerUser.CustomerNumberEnabled", @@ -145,8 +145,8 @@ before you can assign them to all subcategories and products.
builder.AddOrUpdate("Admin.Configuration.Settings.Tax.VatRequired", "Customers must enter a VATIN", "Kunden mssen eine Steuernummer angeben", - "Specifies whether Customers must enter a VAT identification number.", - "Legt fest, ob Kunden bei der Registrierung eine Steuernummer angeben mssen."); + "Specifies whether customers must enter a VAT identification number.", + "Legt fest, ob Kunden bei der Registrierung eine Steuernummer angeben mssen."); builder.AddOrUpdate("Account.Fields.Vat.Required", "Please enter your VATIN", diff --git a/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs b/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs index 2073f9aecc..1c6e87e649 100644 --- a/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs +++ b/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs @@ -278,6 +278,23 @@ public void MigrateLocaleResources(LocaleResourcesBuilder builder) "Zeichenkette prfen", "Enter any string to check the SEO name creation. Changed settings must be saved before.", "Geben Sie eine beliebige Zeichenkette ein, um daraus den SEO Namen zu erstellen. Genderte Einstellungen mssen zuvor gespeichert werden."); + + + builder.AddOrUpdate("Admin.System.Warnings.NoPermissionsDefined", + "There are no permissions defined.", + "Es sind keine Zugriffsrechte festgelegt."); + + builder.AddOrUpdate("Admin.System.Warnings.NoCustomerRolesDefined", + "There are no customer roles defined.", + "Es sind keine Kundengruppen festgelegt."); + + builder.AddOrUpdate("Admin.System.Warnings.AccessDeniedToAnonymousRequest", + "Access denied to anonymous request on {0}.", + "Zugriffsverweigerung durch anonyme Anfrage bei {0}."); + + builder.AddOrUpdate("Admin.System.Warnings.AccessDeniedToUser", + "Access denied to user #{0} '{1}' on {2}.", + "Zugriffsverweigerung durch Kunde #{0} '{1}' bei {2}."); } } } diff --git a/src/Libraries/SmartStore.Services/Security/PermissionService.cs b/src/Libraries/SmartStore.Services/Security/PermissionService.cs index 3ea2815466..a3ada9721a 100644 --- a/src/Libraries/SmartStore.Services/Security/PermissionService.cs +++ b/src/Libraries/SmartStore.Services/Security/PermissionService.cs @@ -10,10 +10,10 @@ namespace SmartStore.Services.Security { - /// - /// Permission service - /// - public partial class PermissionService : IPermissionService + /// + /// Permission service + /// + public partial class PermissionService : IPermissionService { #region Constants /// @@ -141,9 +141,11 @@ orderby pr.Id /// Permissions public virtual IList GetAllPermissionRecords() { - var query = from pr in _permissionRecordRepository.Table - orderby pr.Name - select pr; + var query = + from pr in _permissionRecordRepository.Table + orderby pr.Category, pr.Name + select pr; + var permissions = query.ToList(); return permissions; } diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/SecurityController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/SecurityController.cs index 794c33e0f8..45b5aa901a 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/SecurityController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/SecurityController.cs @@ -1,13 +1,11 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using System.Web.Mvc; using SmartStore.Admin.Models.Customers; using SmartStore.Admin.Models.Security; using SmartStore.Core; -using SmartStore.Services.Customers; -using SmartStore.Services.Localization; using SmartStore.Core.Logging; +using SmartStore.Services.Customers; using SmartStore.Services.Security; using SmartStore.Web.Framework.Controllers; using SmartStore.Web.Framework.Security; @@ -22,7 +20,6 @@ public class SecurityController : AdminControllerBase private readonly IWorkContext _workContext; private readonly IPermissionService _permissionService; private readonly ICustomerService _customerService; - private readonly ILocalizationService _localizationService; #endregion @@ -30,12 +27,11 @@ public class SecurityController : AdminControllerBase public SecurityController(IWorkContext workContext, IPermissionService permissionService, - ICustomerService customerService, ILocalizationService localizationService) + ICustomerService customerService) { this._workContext = workContext; this._permissionService = permissionService; this._customerService = customerService; - this._localizationService = localizationService; } #endregion  @@ -45,14 +41,15 @@ public SecurityController(IWorkContext workContext, public ActionResult AccessDenied(string pageUrl) { var currentCustomer = _workContext.CurrentCustomer; + if (currentCustomer == null || currentCustomer.IsGuest()) { - Logger.Information(string.Format("Access denied to anonymous request on {0}", pageUrl)); + Logger.Information(T("Admin.System.Warnings.AccessDeniedToAnonymousRequest", pageUrl.NaIfEmpty())); return View(); } - Logger.Information(string.Format("Access denied to user #{0} '{1}' on {2}", currentCustomer.Email, currentCustomer.Email, pageUrl)); - + Logger.Information(T("Admin.System.Warnings.AccessDeniedToUser", + currentCustomer.Email.NaIfEmpty(), currentCustomer.Email.NaIfEmpty(), pageUrl.NaIfEmpty())); return View(); } @@ -66,30 +63,38 @@ public ActionResult Permissions() var permissionRecords = _permissionService.GetAllPermissionRecords(); var customerRoles = _customerService.GetAllCustomerRoles(true); + foreach (var pr in permissionRecords) { - model.AvailablePermissions.Add(new PermissionRecordModel() + model.AvailablePermissions.Add(new PermissionRecordModel { Name = pr.Name, - SystemName = pr.SystemName + SystemName = pr.SystemName, + Category = pr.Category }); } + foreach (var cr in customerRoles) { - model.AvailableCustomerRoles.Add(new CustomerRoleModel() + model.AvailableCustomerRoles.Add(new CustomerRoleModel { Id = cr.Id, Name = cr.Name }); } - foreach (var pr in permissionRecords) - foreach (var cr in customerRoles) - { - bool allowed = pr.CustomerRoles.Where(x => x.Id == cr.Id).ToList().Count() > 0; - if (!model.Allowed.ContainsKey(pr.SystemName)) - model.Allowed[pr.SystemName] = new Dictionary(); - model.Allowed[pr.SystemName][cr.Id] = allowed; - } + + foreach (var pr in permissionRecords) + { + foreach (var cr in customerRoles) + { + var allowed = pr.CustomerRoles.Any(x => x.Id == cr.Id); + + if (!model.Allowed.ContainsKey(pr.SystemName)) + model.Allowed[pr.SystemName] = new Dictionary(); + + model.Allowed[pr.SystemName][cr.Id] = allowed; + } + } return View(model); } @@ -103,38 +108,38 @@ public ActionResult PermissionsSave(FormCollection form) var permissionRecords = _permissionService.GetAllPermissionRecords(); var customerRoles = _customerService.GetAllCustomerRoles(true); - foreach (var cr in customerRoles) { - string formKey = "allow_" + cr.Id; - var permissionRecordSystemNamesToRestrict = form[formKey] != null ? form[formKey].Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList() : new List(); + var restrictedSystemNames = form["allow_" + cr.Id.ToString()].SplitSafe(",").ToList(); - foreach (var pr in permissionRecords) + foreach (var permission in permissionRecords) { + bool allow = restrictedSystemNames.Contains(permission.SystemName); - bool allow = permissionRecordSystemNamesToRestrict.Contains(pr.SystemName); if (allow) { - if (pr.CustomerRoles.Where(x => x.Id == cr.Id).FirstOrDefault() == null) + if (!permission.CustomerRoles.Any(x => x.Id == cr.Id)) { - pr.CustomerRoles.Add(cr); - _permissionService.UpdatePermissionRecord(pr); + permission.CustomerRoles.Add(cr); + _permissionService.UpdatePermissionRecord(permission); } } else { - if (pr.CustomerRoles.Where(x => x.Id == cr.Id).FirstOrDefault() != null) + if (permission.CustomerRoles.Any(x => x.Id == cr.Id)) { - pr.CustomerRoles.Remove(cr); - _permissionService.UpdatePermissionRecord(pr); + permission.CustomerRoles.Remove(cr); + _permissionService.UpdatePermissionRecord(permission); } } } } - NotifySuccess(_localizationService.GetResource("Admin.Configuration.ACL.Updated")); + NotifySuccess(T("Admin.Configuration.ACL.Updated")); + return RedirectToAction("Permissions"); } + #endregion } } diff --git a/src/Presentation/SmartStore.Web/Administration/Models/Security/PermissionRecordModel.cs b/src/Presentation/SmartStore.Web/Administration/Models/Security/PermissionRecordModel.cs index 10840b978c..b444eaa04b 100644 --- a/src/Presentation/SmartStore.Web/Administration/Models/Security/PermissionRecordModel.cs +++ b/src/Presentation/SmartStore.Web/Administration/Models/Security/PermissionRecordModel.cs @@ -6,5 +6,25 @@ public class PermissionRecordModel : ModelBase { public string Name { get; set; } public string SystemName { get; set; } - } + public string Category { get; set; } + + public string CategoryLabel + { + get + { + switch (Category) + { + case "PublicStore": + case "Standard": + return "label-success"; + + case "Plugin": + return ""; + + default: + return "label-info"; + } + } + } + } } \ No newline at end of file diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Security/Permissions.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Security/Permissions.cshtml index 0d02bfd4b2..743c8f9d8f 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Security/Permissions.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Security/Permissions.cshtml @@ -1,6 +1,6 @@ -@model PermissionMappingModel +@using SmartStore.Utilities; +@model PermissionMappingModel @{ - //page title ViewBag.Title = T("Admin.Configuration.ACL").Text; } @using (Html.BeginForm()) @@ -11,7 +11,9 @@ @T("Admin.Configuration.ACL")
- +
@@ -19,12 +21,16 @@ @if (Model.AvailablePermissions.Count == 0) - { - No permissions defined - } - else if (Model.AvailableCustomerRoles.Count == 0) - { - No customer roles available + { +
+ @T("Admin.System.Warnings.NoPermissionsDefined") +
+ } + else if (Model.AvailableCustomerRoles.Count == 0) + { +
+ @T("Admin.System.Warnings.NoCustomerRolesDefined") +
} else { @@ -48,6 +54,7 @@ { + @Inflector.Titleize(pr.Category).NaIfEmpty() @pr.Name @foreach (var cr in Model.AvailableCustomerRoles) @@ -66,5 +73,4 @@ - } From 8f8a8afb04b0a4d778f83bb8d6fb16871e4cdbca Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Mon, 4 Jan 2016 21:13:03 +0100 Subject: [PATCH 128/626] Resolves #26 Company or name in order list --- .../Controllers/OrderController.cs | 27 +- .../Models/Orders/OrderListModel.cs | 5 +- .../Models/Orders/OrderModel.cs | 3 + .../Administration/Views/Order/List.cshtml | 252 +++++++++--------- 4 files changed, 150 insertions(+), 137 deletions(-) diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/OrderController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/OrderController.cs index fd82849786..f7adf8147d 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/OrderController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/OrderController.cs @@ -89,8 +89,9 @@ public partial class OrderController : AdminControllerBase private readonly MeasureSettings _measureSettings; private readonly PdfSettings _pdfSettings; private readonly AddressSettings _addressSettings; + private readonly AdminAreaSettings _adminAreaSettings; - private readonly ICheckoutAttributeFormatter _checkoutAttributeFormatter; + private readonly ICheckoutAttributeFormatter _checkoutAttributeFormatter; private readonly IPdfConverter _pdfConverter; private readonly ICommonServices _services; private readonly Lazy _pictureService; @@ -124,7 +125,8 @@ public OrderController(IOrderService orderService, ICustomerActivityService customerActivityService, CatalogSettings catalogSettings, CurrencySettings currencySettings, TaxSettings taxSettings, MeasureSettings measureSettings, PdfSettings pdfSettings, AddressSettings addressSettings, - IPdfConverter pdfConverter, ICommonServices services, Lazy pictureService) + AdminAreaSettings adminAreaSettings, + IPdfConverter pdfConverter, ICommonServices services, Lazy pictureService) { this._orderService = orderService; this._orderReportService = orderReportService; @@ -167,6 +169,7 @@ public OrderController(IOrderService orderService, this._measureSettings = measureSettings; this._pdfSettings = pdfSettings; this._addressSettings = addressSettings; + this._adminAreaSettings = adminAreaSettings; this._checkoutAttributeFormatter = checkoutAttributeFormatter; _pdfConverter = pdfConverter; @@ -787,15 +790,20 @@ public ActionResult List(OrderListModel model) if (!_permissionService.Authorize(StandardPermissionProvider.ManageOrders)) return AccessDeniedView(); - model.AvailableOrderStatuses = OrderStatus.Pending.ToSelectList(false).ToList(); + var allStores = _storeService.GetAllStores(); + + model.AvailableOrderStatuses = OrderStatus.Pending.ToSelectList(false).ToList(); model.AvailablePaymentStatuses = PaymentStatus.Pending.ToSelectList(false).ToList(); model.AvailableShippingStatuses = ShippingStatus.NotYetShipped.ToSelectList(false).ToList(); - //stores - model.AvailableStores.AddRange(_storeService.GetAllStores().ToList().ToSelectListItems()); - model.AvailableStores.Insert(0, new SelectListItem() { Text = _localizationService.GetResource("Admin.Common.All"), Value = "0" }); + model.AvailableStores = allStores + .Select(x => new SelectListItem { Text = x.Name, Value = x.Id.ToString() }) + .ToList(); - return View(model); + model.GridPageSize = _adminAreaSettings.GridPageSize; + model.StoreCount = allStores.Count; + + return View(model); } [GridAction(EnableCustomBinding = true)] @@ -823,12 +831,13 @@ public ActionResult OrderList(GridCommand command, OrderListModel model) { Id = x.Id, OrderNumber = x.GetOrderNumber(), - StoreName = store != null ? store.Name : "Unknown", + StoreName = (store != null ? store.Name : "".NaIfEmpty()), OrderTotal = _priceFormatter.FormatPrice(x.OrderTotal, true, false), OrderStatus = x.OrderStatus.GetLocalizedEnum(_localizationService, _workContext), PaymentStatus = x.PaymentStatus.GetLocalizedEnum(_localizationService, _workContext), ShippingStatus = x.ShippingStatus.GetLocalizedEnum(_localizationService, _workContext), - CustomerEmail = x.BillingAddress.Email, + CustomerName = x.BillingAddress.GetFullName(), + CustomerEmail = x.BillingAddress.Email, CreatedOn = _dateTimeHelper.ConvertToUserTime(x.CreatedOnUtc, DateTimeKind.Utc), HasNewPaymentNotification = x.HasNewPaymentNotification }; diff --git a/src/Presentation/SmartStore.Web/Administration/Models/Orders/OrderListModel.cs b/src/Presentation/SmartStore.Web/Administration/Models/Orders/OrderListModel.cs index 2d64f5216c..8fc20246ad 100644 --- a/src/Presentation/SmartStore.Web/Administration/Models/Orders/OrderListModel.cs +++ b/src/Presentation/SmartStore.Web/Administration/Models/Orders/OrderListModel.cs @@ -54,9 +54,10 @@ public OrderListModel() [AllowHtml] public string GoDirectlyToNumber { get; set; } - + public int GridPageSize { get; set; } + public int StoreCount { get; set; } - public IList AvailableOrderStatuses { get; set; } + public IList AvailableOrderStatuses { get; set; } public IList AvailablePaymentStatuses { get; set; } public IList AvailableShippingStatuses { get; set; } public IList AvailableStores { get; set; } diff --git a/src/Presentation/SmartStore.Web/Administration/Models/Orders/OrderModel.cs b/src/Presentation/SmartStore.Web/Administration/Models/Orders/OrderModel.cs index 17c2b7be51..c622929029 100644 --- a/src/Presentation/SmartStore.Web/Administration/Models/Orders/OrderModel.cs +++ b/src/Presentation/SmartStore.Web/Administration/Models/Orders/OrderModel.cs @@ -37,10 +37,13 @@ public OrderModel() //customer info [SmartResourceDisplayName("Admin.Orders.Fields.Customer")] public int CustomerId { get; set; } + + [SmartResourceDisplayName("Admin.Orders.List.CustomerName")] public string CustomerName { get; set; } [SmartResourceDisplayName("Admin.Orders.Fields.CustomerEmail")] public string CustomerEmail { get; set; } + [SmartResourceDisplayName("Admin.Orders.Fields.CustomerIP")] public string CustomerIp { get; set; } diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Order/List.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Order/List.cshtml index 3e50f7232c..47e12fdb99 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Order/List.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Order/List.cshtml @@ -1,10 +1,10 @@ @model OrderListModel @using Telerik.Web.Mvc.UI @{ - var gridPageSize = EngineContext.Current.Resolve().GridPageSize; - var hideProfitReport = false; - - ViewBag.Title = T("Admin.Orders").Text; + var hideProfitReport = false; + var allString = T("Admin.Common.All").Text; + + ViewBag.Title = T("Admin.Orders").Text; } @using (Html.BeginForm()) @@ -39,39 +39,40 @@ @Html.Widget("admin_button_toolbar_after") - - - - - - - - - - - - - - - - - + +
- @Html.SmartLabelFor(model => model.StartDate) - - @Html.EditorFor(model => model.StartDate) -
- @Html.SmartLabelFor(model => model.EndDate) - - @Html.EditorFor(model => Model.EndDate) -
- @Html.SmartLabelFor(model => model.CustomerName) - - @Html.EditorFor(model => Model.CustomerName) -
- @Html.SmartLabelFor(model => model.CustomerEmail) - - @Html.EditorFor(model => Model.CustomerEmail) -
+ + + + + + + + + + + + + + + + - - - + + - - - - - - - - - + + - - - + + + + @if (Model.StoreCount > 1) + { + + + + + } - - - - - - + + + + + + + + + - - - - - -
+ @Html.SmartLabelFor(model => model.StartDate) + + @Html.EditorFor(model => model.StartDate) +
+ @Html.SmartLabelFor(model => model.EndDate) + + @Html.EditorFor(model => Model.EndDate) +
+ @Html.SmartLabelFor(model => model.CustomerName) + + @Html.EditorFor(model => Model.CustomerName) +
+ @Html.SmartLabelFor(model => model.CustomerEmail) + + @Html.EditorFor(model => Model.CustomerEmail) +
@Html.SmartLabelFor(model => model.OrderStatusIds) @@ -80,69 +81,72 @@ @Html.DropDownList("OrderStatusIds", Model.AvailableOrderStatuses, null, new { multiple = "multiple" })
- @Html.SmartLabelFor(model => model.PaymentStatusIds) - +
+ @Html.SmartLabelFor(model => model.PaymentStatusIds) + @Html.DropDownList("PaymentStatusIds", Model.AvailablePaymentStatuses, null, new { multiple = "multiple" }) -
- @Html.SmartLabelFor(model => model.ShippingStatusIds) - - @Html.DropDownList("ShippingStatusIds", Model.AvailableShippingStatuses, null, new { multiple = "multiple" }) -
- @Html.SmartLabelFor(model => model.StoreId) - - @Html.DropDownList("StoreId", Model.AvailableStores) -
- @Html.SmartLabelFor(model => model.OrderGuid) - - @Html.EditorFor(model => Model.OrderGuid) -
+ @Html.SmartLabelFor(model => model.ShippingStatusIds) + + @Html.DropDownList("ShippingStatusIds", Model.AvailableShippingStatuses, null, new { multiple = "multiple" }) +
+ @Html.SmartLabelFor(model => model.StoreId) + + @Html.DropDownListFor(model => model.StoreId, Model.AvailableStores, allString) +
- @Html.SmartLabelFor(model => model.OrderNumber) - - @Html.EditorFor(model => Model.OrderNumber) -
- @Html.SmartLabelFor(model => model.GoDirectlyToNumber) - - @Html.EditorFor(model => Model.GoDirectlyToNumber) - + @Html.SmartLabelFor(model => model.OrderGuid) + + @Html.EditorFor(model => Model.OrderGuid) +
+ @Html.SmartLabelFor(model => model.OrderNumber) + + @Html.EditorFor(model => Model.OrderNumber) +
+ @Html.SmartLabelFor(model => model.GoDirectlyToNumber) + + @Html.EditorFor(model => Model.GoDirectlyToNumber) + -
-   - - -
+ + + + +   + + + + + +

@@ -150,29 +154,31 @@ @(Html.Telerik().Grid() - .Name("orders-grid") - .ClientEvents(events => events - .OnDataBinding("onDataBinding") - .OnDataBound("onDataBound") - .OnComplete("onComplete")) - .Columns(columns => - { - columns.Bound(x => x.Id) - .ClientTemplate("") - .Title("") - .Width(50) - .HtmlAttributes(new { style = "text-align:center" }) - .HeaderHtmlAttributes(new { style = "text-align:center" }); + .Name("orders-grid") + .ClientEvents(events => events + .OnDataBinding("onDataBinding") + .OnDataBound("onDataBound") + .OnComplete("onComplete")) + .Columns(columns => + { + columns.Bound(x => x.Id) + .ClientTemplate("") + .Title("") + .Width(50) + .HtmlAttributes(new { style = "text-align:center" }) + .HeaderHtmlAttributes(new { style = "text-align:center" }); - columns.Bound(x => x.OrderNumber) + columns.Bound(x => x.OrderNumber) .ClientTemplate(@Html.LabeledOrderNumber()); - columns.Bound(x => x.OrderStatus); - columns.Bound(x => x.PaymentStatus); - columns.Bound(x => x.ShippingStatus); - columns.Bound(x => x.CustomerEmail); - columns.Bound(x => x.StoreName); - columns.Bound(x => x.CreatedOn); - columns.Bound(x => x.OrderTotal) + columns.Bound(x => x.OrderStatus); + columns.Bound(x => x.PaymentStatus); + columns.Bound(x => x.ShippingStatus); + columns.Bound(x => x.CustomerName); + columns.Bound(x => x.CustomerEmail); + columns.Bound(x => x.StoreName) + .Hidden(Model.StoreCount <= 1); + columns.Bound(x => x.CreatedOn); + columns.Bound(x => x.OrderTotal) .Width(180) .RightAlign() .FooterTemplate( @@ -184,17 +190,11 @@ (hideProfitReport ? "" : @T("Admin.Orders.Report.Profit").Text), @T("Admin.Orders.Report.Tax").Text, @T("Admin.Orders.Report.Total").Text)); - columns.Bound(x => x.Id) - .Template(x => Html.ActionLink(T("Admin.Common.View").Text, "Edit", new { id = x.Id })) - .ClientTemplate("\">" + T("Admin.Common.View").Text + "") - .Width(50) - .Centered() - .Title(T("Admin.Common.View").Text); - }) - .Pageable(settings => settings.PageSize(gridPageSize).Position(GridPagerPosition.Both)) - .DataBinding(dataBinding => dataBinding.Ajax().Select("OrderList", "Order")) + }) + .Pageable(settings => settings.PageSize(Model.GridPageSize).Position(GridPagerPosition.Both)) + .DataBinding(dataBinding => dataBinding.Ajax().Select("OrderList", "Order")) .PreserveGridState() - .EnableCustomBinding(true)) + .EnableCustomBinding(true)) From 203765ac463601a49c5d41624186d4cbd1d744d4 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Mon, 4 Jan 2016 21:18:41 +0100 Subject: [PATCH 129/626] Updated changelog --- changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.md b/changelog.md index ac7dd3701f..2decbbfa2f 100644 --- a/changelog.md +++ b/changelog.md @@ -65,6 +65,7 @@ * Simplified handling of SEO names * URLs are not converted to lower case anymore * Product grid sortable by name, price and created on +* #26 Display company or name in order list ### Bugfixes * #523 Redirecting to payment provider performed by core instead of plugin From 2d07edba69861ffb3ddaa25b73181f686b10e457 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Tue, 5 Jan 2016 12:33:42 +0100 Subject: [PATCH 130/626] Added inline editing of country grid. Also resolves #96 --- changelog.md | 1 + .../201512151526290_ImportFramework.cs | 4 + .../Stores/StoreMappingService.cs | 2 +- .../Controllers/SmartController.cs | 17 ++ .../Controllers/CountryController.cs | 189 ++++++++++-------- .../Models/Directory/CountryListModel.cs | 9 + .../Administration/SmartStore.Admin.csproj | 1 + .../Administration/Views/Country/List.cshtml | 112 ++++++----- 8 files changed, 203 insertions(+), 132 deletions(-) create mode 100644 src/Presentation/SmartStore.Web/Administration/Models/Directory/CountryListModel.cs diff --git a/changelog.md b/changelog.md index 2decbbfa2f..72610122db 100644 --- a/changelog.md +++ b/changelog.md @@ -66,6 +66,7 @@ * URLs are not converted to lower case anymore * Product grid sortable by name, price and created on * #26 Display company or name in order list +* Added inline editing of country grid ### Bugfixes * #523 Redirecting to payment provider performed by core instead of plugin diff --git a/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs b/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs index 1c6e87e649..24f368ef69 100644 --- a/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs +++ b/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs @@ -295,6 +295,10 @@ public void MigrateLocaleResources(LocaleResourcesBuilder builder) builder.AddOrUpdate("Admin.System.Warnings.AccessDeniedToUser", "Access denied to user #{0} '{1}' on {2}.", "Zugriffsverweigerung durch Kunde #{0} '{1}' bei {2}."); + + builder.AddOrUpdate("Admin.Configuration.Countries.CannotDeleteDueToAssociatedAddresses", + "The country cannaot be deleted because it has associated addresses.", + "Das Land kann nicht gelscht werden, weil ihm Adressen zugeordnet sind."); } } } diff --git a/src/Libraries/SmartStore.Services/Stores/StoreMappingService.cs b/src/Libraries/SmartStore.Services/Stores/StoreMappingService.cs index da282801ef..04ff4206ff 100644 --- a/src/Libraries/SmartStore.Services/Stores/StoreMappingService.cs +++ b/src/Libraries/SmartStore.Services/Stores/StoreMappingService.cs @@ -219,7 +219,7 @@ public virtual void UpdateStoreMapping(StoreMapping storeMapping) public virtual int[] GetStoresIdsWithAccess(T entity) where T : BaseEntity, IStoreMappingSupported { if (entity == null) - throw new ArgumentNullException("entity"); + return new int[0]; int entityId = entity.Id; string entityName = typeof(T).Name; diff --git a/src/Presentation/SmartStore.Web.Framework/Controllers/SmartController.cs b/src/Presentation/SmartStore.Web.Framework/Controllers/SmartController.cs index 3b6cf51813..a5169e45c4 100644 --- a/src/Presentation/SmartStore.Web.Framework/Controllers/SmartController.cs +++ b/src/Presentation/SmartStore.Web.Framework/Controllers/SmartController.cs @@ -95,6 +95,23 @@ protected virtual void NotifyError(Exception exception, bool durable = true, boo Services.Notifier.Error(exception.ToAllMessages(), durable); } + /// + /// Pushes an error message to the notification queue that the access to a resource has been denied + /// + /// A value indicating whether a message should be persisted for the next request + /// A value indicating whether the message should be logged + protected virtual void NotifyAccessDenied(bool durable = true, bool log = false) + { + var message = T("Admin.AccessDenied.Description"); + + if (log) + { + Logger.Error(message, null, Services.WorkContext.CurrentCustomer); + } + + Services.Notifier.Error(message, durable); + } + protected virtual ActionResult RedirectToReferrer() { if (Request.UrlReferrer != null && Request.UrlReferrer.ToString().HasValue()) diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/CountryController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/CountryController.cs index 17300117c2..bf67df0dae 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/CountryController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/CountryController.cs @@ -3,8 +3,8 @@ using System.Linq; using System.Web.Mvc; using SmartStore.Admin.Models.Directory; -using SmartStore.Core; using SmartStore.Core.Domain.Directory; +using SmartStore.Services; using SmartStore.Services.Common; using SmartStore.Services.Directory; using SmartStore.Services.Localization; @@ -24,37 +24,31 @@ public class CountryController : AdminControllerBase private readonly ICountryService _countryService; private readonly IStateProvinceService _stateProvinceService; - private readonly ILocalizationService _localizationService; private readonly IAddressService _addressService; - private readonly IPermissionService _permissionService; private readonly ILocalizedEntityService _localizedEntityService; private readonly ILanguageService _languageService; - private readonly IStoreService _storeService; private readonly IStoreMappingService _storeMappingService; + private readonly ICommonServices _services; - #endregion + #endregion #region Constructors - public CountryController(ICountryService countryService, + public CountryController(ICountryService countryService, IStateProvinceService stateProvinceService, - ILocalizationService localizationService, IAddressService addressService, - IPermissionService permissionService, ILocalizedEntityService localizedEntityService, ILanguageService languageService, - IStoreService storeService, - IStoreMappingService storeMappingService) + IStoreMappingService storeMappingService, + ICommonServices services) { _countryService = countryService; _stateProvinceService = stateProvinceService; - _localizationService = localizationService; _addressService = addressService; - _permissionService = permissionService; _localizedEntityService = localizedEntityService; _languageService = languageService; - _storeService = storeService; _storeMappingService = storeMappingService; + _services = services; } #endregion  @@ -66,10 +60,7 @@ private void UpdateLocales(Country country, CountryModel model) { foreach (var localized in model.Locales) { - _localizedEntityService.SaveLocalizedValue(country, - x => x.Name, - localized.Name, - localized.LanguageId); + _localizedEntityService.SaveLocalizedValue(country, x => x.Name, localized.Name, localized.LanguageId); } } @@ -78,10 +69,7 @@ private void UpdateLocales(StateProvince stateProvince, StateProvinceModel model { foreach (var localized in model.Locales) { - _localizedEntityService.SaveLocalizedValue(stateProvince, - x => x.Name, - localized.Name, - localized.LanguageId); + _localizedEntityService.SaveLocalizedValue(stateProvince, x => x.Name, localized.Name, localized.LanguageId); } } @@ -91,19 +79,14 @@ private void PrepareCountryModel(CountryModel model, Country country, bool exclu if (model == null) throw new ArgumentNullException("model"); - var allStores = _storeService.GetAllStores(); + var allStores = _services.StoreService.GetAllStores(); model.AvailableStores = allStores.Select(s => s.ToModel()).ToList(); if (!excludeProperties) { - if (country != null) - model.SelectedStoreIds = _storeMappingService.GetStoresIdsWithAccess(country); - else - model.SelectedStoreIds = new int[0]; + model.SelectedStoreIds = _storeMappingService.GetStoresIdsWithAccess(country); } - - ViewBag.StoreCount = allStores.Count; } #endregion @@ -117,40 +100,85 @@ public ActionResult Index() public ActionResult List() { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCountries)) + if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageCountries)) return AccessDeniedView(); - var countries = _countryService.GetAllCountries(true); - var model = new GridModel - { - Data = countries.Select(x => x.ToModel()), - Total = countries.Count - }; - return View(model); + var allStores = _services.StoreService.GetAllStores(); + + var model = new CountryListModel + { + StoreCount = allStores.Count + }; + + return View(model); } [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult CountryList(GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCountries)) - return AccessDeniedView(); + var model = new GridModel(); - var countries = _countryService.GetAllCountries(true); - var model = new GridModel - { - Data = countries.Select(x => x.ToModel()), - Total = countries.Count - }; + if (_services.Permissions.Authorize(StandardPermissionProvider.ManageCountries)) + { + var countries = _countryService.GetAllCountries(true); + + model.Data = countries.Select(x => x.ToModel()); + model.Total = countries.Count; + } + else + { + model.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } return new JsonResult { Data = model }; } - - public ActionResult Create() + + [GridAction(EnableCustomBinding = true)] + public ActionResult CountryUpdate(CountryModel model, GridCommand command) + { + if (_services.Permissions.Authorize(StandardPermissionProvider.ManageCountries)) + { + if (!ModelState.IsValid) + { + var modelStateErrors = ModelState.Values.SelectMany(x => x.Errors).Select(x => x.ErrorMessage); + return Content(modelStateErrors.FirstOrDefault()); + } + + var country = _countryService.GetCountryById(model.Id); + + country = model.ToEntity(country); + _countryService.UpdateCountry(country); + } + + return CountryList(command); + } + + [GridAction(EnableCustomBinding = true)] + public ActionResult CountryDelete(int id, GridCommand command) + { + if (_services.Permissions.Authorize(StandardPermissionProvider.ManageCountries)) + { + if (_addressService.GetAddressTotalByCountryId(id) > 0) + { + return Content(T("Admin.Configuration.Countries.CannotDeleteDueToAssociatedAddresses")); + } + + var country = _countryService.GetCountryById(id); + + _countryService.DeleteCountry(country); + } + + return CountryList(command); + } + + public ActionResult Create() { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCountries)) + if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageCountries)) return AccessDeniedView(); var model = new CountryModel(); @@ -169,7 +197,7 @@ public ActionResult Create() [HttpPost, ParameterBasedOnFormName("save-continue", "continueEditing")] public ActionResult Create(CountryModel model, bool continueEditing) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCountries)) + if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageCountries)) return AccessDeniedView(); if (ModelState.IsValid) @@ -181,7 +209,7 @@ public ActionResult Create(CountryModel model, bool continueEditing) _storeMappingService.SaveStoreMappings(country, model.SelectedStoreIds); - NotifySuccess(_localizationService.GetResource("Admin.Configuration.Countries.Added")); + NotifySuccess(T("Admin.Configuration.Countries.Added")); return continueEditing ? RedirectToAction("Edit", new { id = country.Id }) : RedirectToAction("List"); } @@ -193,7 +221,7 @@ public ActionResult Create(CountryModel model, bool continueEditing) public ActionResult Edit(int id) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCountries)) + if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageCountries)) return AccessDeniedView(); var country = _countryService.GetCountryById(id); @@ -215,7 +243,7 @@ public ActionResult Edit(int id) [HttpPost, ParameterBasedOnFormName("save-continue", "continueEditing")] public ActionResult Edit(CountryModel model, bool continueEditing) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCountries)) + if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageCountries)) return AccessDeniedView(); var country = _countryService.GetCountryById(model.Id); @@ -231,7 +259,7 @@ public ActionResult Edit(CountryModel model, bool continueEditing) _storeMappingService.SaveStoreMappings(country, model.SelectedStoreIds); - NotifySuccess(_localizationService.GetResource("Admin.Configuration.Countries.Updated")); + NotifySuccess(T("Admin.Configuration.Countries.Updated")); return continueEditing ? RedirectToAction("Edit", new { id = country.Id }) : RedirectToAction("List"); } @@ -244,7 +272,7 @@ public ActionResult Edit(CountryModel model, bool continueEditing) [HttpPost, ActionName("Delete")] public ActionResult DeleteConfirmed(int id) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCountries)) + if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageCountries)) return AccessDeniedView(); var country = _countryService.GetCountryById(id); @@ -254,11 +282,12 @@ public ActionResult DeleteConfirmed(int id) try { if (_addressService.GetAddressTotalByCountryId(country.Id) > 0) - throw new SmartException("The country can't be deleted. It has associated addresses"); + throw new SmartException(T("Admin.Configuration.Countries.CannotDeleteDueToAssociatedAddresses")); _countryService.DeleteCountry(country); - NotifySuccess(_localizationService.GetResource("Admin.Configuration.Countries.Deleted")); + NotifySuccess(T("Admin.Configuration.Countries.Deleted")); + return RedirectToAction("List"); } catch (Exception exc) @@ -268,7 +297,6 @@ public ActionResult DeleteConfirmed(int id) } } - #endregion #region States / provinces @@ -276,7 +304,7 @@ public ActionResult DeleteConfirmed(int id) [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult States(int countryId, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCountries)) + if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageCountries)) return AccessDeniedView(); var states = _stateProvinceService.GetStateProvincesByCountryId(countryId, true) @@ -287,30 +315,33 @@ public ActionResult States(int countryId, GridCommand command) Data = states, Total = states.Count() }; + return new JsonResult { Data = model }; } - //create public ActionResult StateCreatePopup(int countryId) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCountries)) + if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageCountries)) return AccessDeniedView(); - var model = new StateProvinceModel(); - model.CountryId = countryId; - //locales + var model = new StateProvinceModel + { + CountryId = countryId + }; + AddLocales(_languageService, model.Locales); + return View(model); } [HttpPost] public ActionResult StateCreatePopup(string btnId, string formId, StateProvinceModel model) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCountries)) + if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageCountries)) return AccessDeniedView(); var country = _countryService.GetCountryById(model.CountryId); @@ -327,6 +358,7 @@ public ActionResult StateCreatePopup(string btnId, string formId, StateProvinceM ViewBag.RefreshPage = true; ViewBag.btnId = btnId; ViewBag.formId = formId; + return View(model); } @@ -337,16 +369,15 @@ public ActionResult StateCreatePopup(string btnId, string formId, StateProvinceM //edit public ActionResult StateEditPopup(int id) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCountries)) + if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageCountries)) return AccessDeniedView(); var sp = _stateProvinceService.GetStateProvinceById(id); if (sp == null) - //No state found with the specified id return RedirectToAction("List"); var model = sp.ToModel(); - //locales + AddLocales(_languageService, model.Locales, (locale, languageId) => { locale.Name = sp.GetLocalized(x => x.Name, languageId, false, false); @@ -358,12 +389,11 @@ public ActionResult StateEditPopup(int id) [HttpPost] public ActionResult StateEditPopup(string btnId, string formId, StateProvinceModel model) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCountries)) + if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageCountries)) return AccessDeniedView(); var sp = _stateProvinceService.GetStateProvinceById(model.Id); if (sp == null) - //No state found with the specified id return RedirectToAction("List"); if (ModelState.IsValid) @@ -376,6 +406,7 @@ public ActionResult StateEditPopup(string btnId, string formId, StateProvinceMod ViewBag.RefreshPage = true; ViewBag.btnId = btnId; ViewBag.formId = formId; + return View(model); } @@ -386,7 +417,7 @@ public ActionResult StateEditPopup(string btnId, string formId, StateProvinceMod [GridAction(EnableCustomBinding = true)] public ActionResult StateDelete(int id, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCountries)) + if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageCountries)) return AccessDeniedView(); var state = _stateProvinceService.GetStateProvinceById(id); @@ -394,35 +425,31 @@ public ActionResult StateDelete(int id, GridCommand command) throw new ArgumentException("No state found with the specified id"); if (_addressService.GetAddressTotalByStateProvinceId(state.Id) > 0) - return Content(_localizationService.GetResource("Admin.Configuration.Countries.States.CantDeleteWithAddresses")); + return Content(T("Admin.Configuration.Countries.States.CantDeleteWithAddresses")); int countryId = state.CountryId; _stateProvinceService.DeleteStateProvince(state); - return States(countryId, command); } [AcceptVerbs(HttpVerbs.Get)] public ActionResult GetStatesByCountryId(string countryId, bool? addEmptyStateIfRequired, bool? addAsterisk) { - //permission validation is not required here - + // permission validation is not required here // This action method gets called via an ajax request - int cid = 0; - int.TryParse(countryId, out cid); - /*if (String.IsNullOrEmpty(countryId)) - throw new ArgumentNullException("countryId");*/ + var country = _countryService.GetCountryById(countryId.ToInt()); - var country = _countryService.GetCountryById(cid /* Convert.ToInt32(countryId) */); var states = country != null ? _stateProvinceService.GetStateProvincesByCountryId(country.Id, true).ToList() : new List(); - var result = (from s in states - select new { id = s.Id, name = s.Name }).ToList(); + var result = (from s in states select new { id = s.Id, name = s.Name }).ToList(); + if (addEmptyStateIfRequired.HasValue && addEmptyStateIfRequired.Value && result.Count == 0) - result.Insert(0, new { id = 0, name = _localizationService.GetResource("Admin.Address.OtherNonUS") }); + result.Insert(0, new { id = 0, name = T("Admin.Address.OtherNonUS").Text }); + if (addAsterisk.HasValue && addAsterisk.Value) result.Insert(0, new { id = 0, name = "*" }); + return Json(result, JsonRequestBehavior.AllowGet); } diff --git a/src/Presentation/SmartStore.Web/Administration/Models/Directory/CountryListModel.cs b/src/Presentation/SmartStore.Web/Administration/Models/Directory/CountryListModel.cs new file mode 100644 index 0000000000..ece27d8805 --- /dev/null +++ b/src/Presentation/SmartStore.Web/Administration/Models/Directory/CountryListModel.cs @@ -0,0 +1,9 @@ +using SmartStore.Web.Framework.Modelling; + +namespace SmartStore.Admin.Models.Directory +{ + public class CountryListModel : ModelBase + { + public int StoreCount { get; set; } + } +} \ No newline at end of file diff --git a/src/Presentation/SmartStore.Web/Administration/SmartStore.Admin.csproj b/src/Presentation/SmartStore.Web/Administration/SmartStore.Admin.csproj index 8aa8fd5f3f..c7ca89c0f8 100644 --- a/src/Presentation/SmartStore.Web/Administration/SmartStore.Admin.csproj +++ b/src/Presentation/SmartStore.Web/Administration/SmartStore.Admin.csproj @@ -258,6 +258,7 @@ + diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Country/List.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Country/List.cshtml index 5285bcd4d5..833e3badee 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Country/List.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Country/List.cshtml @@ -1,4 +1,4 @@ -@model Telerik.Web.Mvc.GridModel +@model CountryListModel @using Telerik.Web.Mvc.UI @{ ViewBag.Title = T("Admin.Configuration.Countries").Text; @@ -12,62 +12,74 @@  @T("Admin.Common.AddNew") +
@(Html.Telerik().Grid() - .Name("countries-grid") - .BindTo(Model.Data) - .Columns(columns => - { - columns.Bound(x => x.Name) - .Width(250) - .Template(x => Html.ActionLink(x.Name, "Edit", new { id = x.Id })) - .ClientTemplate("<#= Name #>"); - columns.Bound(x => x.AllowsBilling) - .Width(50) - .Template(item => @Html.SymbolForBool(item.AllowsBilling)) - .ClientTemplate(@Html.SymbolForBool("AllowsBilling")) - .Centered(); - columns.Bound(x => x.AllowsShipping) - .Width(50) - .Template(item => @Html.SymbolForBool(item.AllowsShipping)) - .ClientTemplate(@Html.SymbolForBool("AllowsShipping")) - .Centered(); - columns.Bound(x => x.TwoLetterIsoCode) - .Width(50) - .Centered(); - columns.Bound(x => x.ThreeLetterIsoCode) - .Width(50) - .Centered(); - columns.Bound(x => x.NumericIsoCode) - .Width(50) - .Centered(); - columns.Bound(x => x.SubjectToVat) - .Width(50) - .Template(item => @Html.SymbolForBool(item.SubjectToVat)) - .ClientTemplate(@Html.SymbolForBool("SubjectToVat")) - .Centered(); - columns.Bound(x => x.NumberOfStates) - .Width(50) - .Centered(); - columns.Bound(x => x.DisplayOrder) - .Width(50) - .Centered(); + .Name("countries-grid") + .DataKeys(x => + { + x.Add(y => y.Id).RouteKey("Id"); + }) + .Editable(x => + { + x.Mode(GridEditMode.InLine); + }) + .Columns(columns => + { + columns.Bound(x => x.Name) + .ClientTemplate("<#= Name #>"); + columns.Bound(x => x.AllowsBilling) + .Width(50) + .ClientTemplate(@Html.SymbolForBool("AllowsBilling")) + .Centered(); + columns.Bound(x => x.AllowsShipping) + .ClientTemplate(@Html.SymbolForBool("AllowsShipping")) + .Centered(); + columns.Bound(x => x.TwoLetterIsoCode) + .Centered(); + columns.Bound(x => x.ThreeLetterIsoCode) + .Centered(); + columns.Bound(x => x.NumericIsoCode) + .Centered(); + columns.Bound(x => x.SubjectToVat) + .ClientTemplate(@Html.SymbolForBool("SubjectToVat")) + .Centered(); + columns.Bound(x => x.NumberOfStates) + .ReadOnly() + .Centered(); + columns.Bound(x => x.DisplayOrder) + .Centered(); columns.Bound(x => x.LimitedToStores) - .Template(item => @Html.SymbolForBool(item.LimitedToStores)) .ClientTemplate(@Html.SymbolForBool("LimitedToStores")) .Centered() - .Width(100) - .Hidden(ViewBag.StoreCount <= 1); - columns.Bound(x => x.Published) - .Width(50) - .Template(item => @Html.SymbolForBool(item.Published)) - .ClientTemplate(@Html.SymbolForBool("Published")) - .Centered(); - }) - .DataBinding(dataBinding => dataBinding.Ajax().Select("CountryList", "Country")) - .EnableCustomBinding(true)) + .ReadOnly() + .Hidden(Model.StoreCount <= 1); + columns.Bound(x => x.Published) + .ClientTemplate(@Html.SymbolForBool("Published")) + .Centered(); + columns.Command(commands => + { + commands.Edit().Localize(T); + commands.Delete().Localize(T); + }); + }) + .DataBinding(dataBinding => dataBinding.Ajax() + .Select("CountryList", "Country") + .Update("CountryUpdate", "Country") + .Delete("CountryDelete", "Country") + ) + .ClientEvents(x => x.OnError("CountryGrid_onError")) + .PreserveGridState() + .EnableCustomBinding(true))
+ + From 718323ce9f06773c37a7bbd5e486c0da43fd805f Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Tue, 5 Jan 2016 14:03:26 +0100 Subject: [PATCH 131/626] Product import: Store mappings were not applied when inserting new records --- changelog.md | 1 + .../Catalog/Importer/ProductImporter.cs | 38 ++++++++++++++++--- .../Controllers/SmartController.cs | 3 +- .../Controllers/ImportController.cs | 2 +- .../Views/Import/_ColumnMappings.cshtml | 2 +- 5 files changed, 37 insertions(+), 9 deletions(-) diff --git a/changelog.md b/changelog.md index 72610122db..0ca5d818fc 100644 --- a/changelog.md +++ b/changelog.md @@ -84,6 +84,7 @@ * #805 Product filter is reset if 'product sorting' or 'view mode' or 'amount of displayed products per page' is changed * Hide link to a topic page if it is limited to stores * #829 Activity log: Searching by customer email out of function +* Product import: Store mappings were not applied when inserting new records ## SmartStore.NET 2.2.2 diff --git a/src/Libraries/SmartStore.Services/Catalog/Importer/ProductImporter.cs b/src/Libraries/SmartStore.Services/Catalog/Importer/ProductImporter.cs index b115a270eb..c4321349f6 100644 --- a/src/Libraries/SmartStore.Services/Catalog/Importer/ProductImporter.cs +++ b/src/Libraries/SmartStore.Services/Catalog/Importer/ProductImporter.cs @@ -367,6 +367,21 @@ private int ProcessSlugs(IImportExecuteContext context, ImportRow[] bat return _urlRecordRepository.Context.SaveChanges(); } + private void ProcessStoreMappings(IImportExecuteContext context, ImportRow[] batch) + { + foreach (var row in batch) + { + var limitedToStore = row.GetDataValue("LimitedToStores"); + + if (limitedToStore) + { + var storeIds = row.GetDataValue>("StoreIds"); + + _storeMappingService.SaveStoreMappings(row.Entity, storeIds == null ? new int[0] : storeIds.ToArray()); + } + } + } + private int ProcessProducts(IImportExecuteContext context, ImportRow[] batch, DateTime utcNow) { _productRepository.AutoCommitEnabled = true; @@ -497,12 +512,6 @@ private int ProcessProducts(IImportExecuteContext context, ImportRow[] row.SetProperty(context.Result, product, (x) => x.AvailableEndDateTimeUtc); row.SetProperty(context.Result, product, (x) => x.LimitedToStores); - var storeIds = row.GetDataValue>("StoreIds"); - if (storeIds != null && storeIds.Any()) - { - _storeMappingService.SaveStoreMappings(product, storeIds.ToArray()); - } - row.SetProperty(context.Result, product, (x) => x.CreatedOnUtc, utcNow); product.UpdatedOnUtc = utcNow; @@ -590,6 +599,23 @@ public void Execute(IImportExecuteContext context) } } + if (segmenter.HasColumn("LimitedToStores") && segmenter.HasColumn("StoreIds")) + { + try + { + _productRepository.Context.AutoDetectChangesEnabled = true; + ProcessStoreMappings(context, batch); + } + catch (Exception exception) + { + context.Result.AddError(exception, segmenter.CurrentSegment, "ProcessStoreMappings"); + } + finally + { + _productRepository.Context.AutoDetectChangesEnabled = false; + } + } + // =========================================================================== // 3.) Import Localizations // =========================================================================== diff --git a/src/Presentation/SmartStore.Web.Framework/Controllers/SmartController.cs b/src/Presentation/SmartStore.Web.Framework/Controllers/SmartController.cs index a5169e45c4..2debc94ede 100644 --- a/src/Presentation/SmartStore.Web.Framework/Controllers/SmartController.cs +++ b/src/Presentation/SmartStore.Web.Framework/Controllers/SmartController.cs @@ -1,5 +1,6 @@ using System; using System.Text; +using System.Web; using System.Web.Mvc; using SmartStore.Core.Localization; using SmartStore.Core.Logging; @@ -92,7 +93,7 @@ protected virtual void NotifyError(Exception exception, bool durable = true, boo LogException(exception); } - Services.Notifier.Error(exception.ToAllMessages(), durable); + Services.Notifier.Error(HttpUtility.HtmlEncode(exception.ToAllMessages()), durable); } /// diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs index 9c2d6b565f..c56638c2a1 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/ImportController.cs @@ -125,7 +125,7 @@ private void PrepareColumnMappingModels(ImportProfile profile, ImportProfileMode } catch (Exception exception) { - NotifyError(exception); + NotifyError(exception, true, false); } } diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Import/_ColumnMappings.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Import/_ColumnMappings.cshtml index 4dc8045232..9e15de2aef 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Import/_ColumnMappings.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Import/_ColumnMappings.cshtml @@ -1,6 +1,6 @@ @using SmartStore.Admin.Models.DataExchange; @model ImportProfileModel -@if (Model.ColumnMappings.Any()) +@if (Model.ColumnMappings != null && Model.ColumnMappings.Any()) {

 

From 9966961092d437f46883a308a2feea4f3dd75f21 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Tue, 5 Jan 2016 14:08:19 +0100 Subject: [PATCH 132/626] Dito new category import --- .../Catalog/Importer/CategoryImporter.cs | 39 ++++++++++++++++--- 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/src/Libraries/SmartStore.Services/Catalog/Importer/CategoryImporter.cs b/src/Libraries/SmartStore.Services/Catalog/Importer/CategoryImporter.cs index e0e5a2bdf2..08e43b0448 100644 --- a/src/Libraries/SmartStore.Services/Catalog/Importer/CategoryImporter.cs +++ b/src/Libraries/SmartStore.Services/Catalog/Importer/CategoryImporter.cs @@ -178,6 +178,21 @@ private int ProcessPictures(IImportExecuteContext context, return num; } + private void ProcessStoreMappings(IImportExecuteContext context, ImportRow[] batch) + { + foreach (var row in batch) + { + var limitedToStore = row.GetDataValue("LimitedToStores"); + + if (limitedToStore) + { + var storeIds = row.GetDataValue>("StoreIds"); + + _storeMappingService.SaveStoreMappings(row.Entity, storeIds == null ? new int[0] : storeIds.ToArray()); + } + } + } + private int ProcessCategories(IImportExecuteContext context, ImportRow[] batch, DateTime utcNow, @@ -249,12 +264,6 @@ private int ProcessCategories(IImportExecuteContext context, category.CategoryTemplateId = templateId; } - var storeIds = row.GetDataValue>("StoreIds"); - if (storeIds != null && storeIds.Any()) - { - _storeMappingService.SaveStoreMappings(category, storeIds.ToArray()); - } - row.SetProperty(context.Result, category, (x) => x.CreatedOnUtc, utcNow); category.UpdatedOnUtc = utcNow; @@ -355,6 +364,24 @@ public void Execute(IImportExecuteContext context) } } + // process store mappings + if (segmenter.HasColumn("LimitedToStores") && segmenter.HasColumn("StoreIds")) + { + try + { + _categoryRepository.Context.AutoDetectChangesEnabled = true; + ProcessStoreMappings(context, batch); + } + catch (Exception exception) + { + context.Result.AddError(exception, segmenter.CurrentSegment, "ProcessStoreMappings"); + } + finally + { + _categoryRepository.Context.AutoDetectChangesEnabled = false; + } + } + // process pictures if (srcToDestId.Any() && segmenter.HasColumn("PictureThumbPath")) { From ef6da8abe065e2b65b1740525ec20310503b8eb5 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Tue, 5 Jan 2016 18:11:26 +0100 Subject: [PATCH 133/626] Faulty permission handling in ajax grid actions (no message, infinite loading icon)(part 1) --- changelog.md | 1 + .../201512151526290_ImportFramework.cs | 6 +- .../Controllers/SmartController.cs | 2 +- .../Controllers/AffiliateController.cs | 121 ++++++------ .../Controllers/BlogController.cs | 135 +++++++------ .../Controllers/CampaignController.cs | 35 ++-- .../Controllers/CategoryController.cs | 168 +++++++++-------- .../CheckoutAttributeController.cs | 90 ++++----- .../Controllers/CommonController.cs | 177 +++++++++--------- .../Controllers/CountryController.cs | 43 +++-- .../Controllers/CurrencyController.cs | 25 ++- .../Controllers/CustomerController.cs | 130 +++++++------ .../Controllers/CustomerRoleController.cs | 25 ++- .../Controllers/DiscountController.cs | 87 ++++----- .../Controllers/EmailAccountController.cs | 34 ++-- .../Controllers/ExportController.cs | 12 +- .../Controllers/GiftCardController.cs | 106 ++++++----- 17 files changed, 664 insertions(+), 533 deletions(-) diff --git a/changelog.md b/changelog.md index 0ca5d818fc..2308726b85 100644 --- a/changelog.md +++ b/changelog.md @@ -85,6 +85,7 @@ * Hide link to a topic page if it is limited to stores * #829 Activity log: Searching by customer email out of function * Product import: Store mappings were not applied when inserting new records +* Faulty permission handling in ajax grid actions (no message, infinite loading icon) ## SmartStore.NET 2.2.2 diff --git a/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs b/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs index 24f368ef69..7de4cc953b 100644 --- a/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs +++ b/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs @@ -297,8 +297,12 @@ public void MigrateLocaleResources(LocaleResourcesBuilder builder) "Zugriffsverweigerung durch Kunde #{0} '{1}' bei {2}."); builder.AddOrUpdate("Admin.Configuration.Countries.CannotDeleteDueToAssociatedAddresses", - "The country cannaot be deleted because it has associated addresses.", + "The country cannot be deleted because it has associated addresses.", "Das Land kann nicht gelscht werden, weil ihm Adressen zugeordnet sind."); + + builder.AddOrUpdate("Admin.Configuration.Countries.States.CantDeleteWithAddresses", + "The state\\province cannot be deleted because it has associated addresses.", + "Das Bundesland\\Region kann nicht gelscht werden, weil ihm Adressen zugeordnet sind."); } } } diff --git a/src/Presentation/SmartStore.Web.Framework/Controllers/SmartController.cs b/src/Presentation/SmartStore.Web.Framework/Controllers/SmartController.cs index 2debc94ede..b5db948b54 100644 --- a/src/Presentation/SmartStore.Web.Framework/Controllers/SmartController.cs +++ b/src/Presentation/SmartStore.Web.Framework/Controllers/SmartController.cs @@ -101,7 +101,7 @@ protected virtual void NotifyError(Exception exception, bool durable = true, boo ///
/// A value indicating whether a message should be persisted for the next request /// A value indicating whether the message should be logged - protected virtual void NotifyAccessDenied(bool durable = true, bool log = false) + protected virtual void NotifyAccessDenied(bool durable = true, bool log = true) { var message = T("Admin.AccessDenied.Description"); diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/AffiliateController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/AffiliateController.cs index e98628b496..cf1e2b3c87 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/AffiliateController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/AffiliateController.cs @@ -24,7 +24,7 @@ namespace SmartStore.Admin.Controllers { - [AdminAuthorize] + [AdminAuthorize] public partial class AffiliateController : AdminControllerBase { #region Fields @@ -156,23 +156,31 @@ public ActionResult List() [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult List(GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageAffiliates)) - return AccessDeniedView(); + var model = new GridModel(); - var affiliates = _affiliateService.GetAllAffiliates(true); - var gridModel = new GridModel - { - Data = affiliates.PagedForCommand(command).Select(x => - { - var m = new AffiliateModel(); - PrepareAffiliateModel(m, x, false); - return m; - }), - Total = affiliates.Count, - }; - return new JsonResult + if (_permissionService.Authorize(StandardPermissionProvider.ManageAffiliates)) + { + var affiliates = _affiliateService.GetAllAffiliates(true); + + model.Data = affiliates.PagedForCommand(command).Select(x => + { + var m = new AffiliateModel(); + PrepareAffiliateModel(m, x, false); + return m; + }); + + model.Total = affiliates.Count; + } + else + { + model.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } + + return new JsonResult { - Data = gridModel + Data = model }; } @@ -287,31 +295,34 @@ public ActionResult Delete(int id) [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult AffiliatedOrderList(int affiliateId, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageAffiliates)) - return AccessDeniedView(); + var model = new GridModel(); - var affiliate = _affiliateService.GetAffiliateById(affiliateId); - if (affiliate == null) - throw new ArgumentException("No affiliate found with the specified id"); + if (_permissionService.Authorize(StandardPermissionProvider.ManageAffiliates)) + { + var affiliate = _affiliateService.GetAffiliateById(affiliateId); + var orders = _orderService.GetAllOrders(affiliate.Id, command.Page - 1, command.PageSize); + + model.Data = orders.Select(order => + { + var orderModel = new AffiliateModel.AffiliatedOrderModel(); + orderModel.Id = order.Id; + orderModel.OrderStatus = order.OrderStatus.GetLocalizedEnum(_localizationService, _workContext); + orderModel.PaymentStatus = order.PaymentStatus.GetLocalizedEnum(_localizationService, _workContext); + orderModel.ShippingStatus = order.ShippingStatus.GetLocalizedEnum(_localizationService, _workContext); + orderModel.OrderTotal = _priceFormatter.FormatPrice(order.OrderTotal, true, false); + orderModel.CreatedOn = _dateTimeHelper.ConvertToUserTime(order.CreatedOnUtc, DateTimeKind.Utc); + return orderModel; + }); + model.Total = orders.TotalCount; + } + else + { + model.Data = Enumerable.Empty(); - var orders = _orderService.GetAllOrders(affiliate.Id, command.Page - 1, command.PageSize); - var model = new GridModel - { - Data = orders.Select(order => - { - var orderModel = new AffiliateModel.AffiliatedOrderModel(); - orderModel.Id = order.Id; - orderModel.OrderStatus = order.OrderStatus.GetLocalizedEnum(_localizationService, _workContext); - orderModel.PaymentStatus = order.PaymentStatus.GetLocalizedEnum(_localizationService, _workContext); - orderModel.ShippingStatus = order.ShippingStatus.GetLocalizedEnum(_localizationService, _workContext); - orderModel.OrderTotal = _priceFormatter.FormatPrice(order.OrderTotal, true, false); - orderModel.CreatedOn = _dateTimeHelper.ConvertToUserTime(order.CreatedOnUtc, DateTimeKind.Utc); - return orderModel; - }), - Total = orders.TotalCount - }; + NotifyAccessDenied(); + } - return new JsonResult + return new JsonResult { Data = model }; @@ -320,19 +331,16 @@ public ActionResult AffiliatedOrderList(int affiliateId, GridCommand command) [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult AffiliatedCustomerList(int affiliateId, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageAffiliates)) - return AccessDeniedView(); + var model = new GridModel(); - var affiliate = _affiliateService.GetAffiliateById(affiliateId); - if (affiliate == null) - throw new ArgumentException("No affiliate found with the specified id"); + if (_permissionService.Authorize(StandardPermissionProvider.ManageAffiliates)) + { + var affiliate = _affiliateService.GetAffiliateById(affiliateId); + var customers = _customerService.GetAllCustomers(affiliate.Id, command.Page - 1, command.PageSize); - var customers = _customerService.GetAllCustomers(affiliate.Id, command.Page - 1, command.PageSize); - var model = new GridModel - { - Data = customers.Select(customer => - { - var customerModel = new AffiliateModel.AffiliatedCustomerModel + model.Data = customers.Select(customer => + { + var customerModel = new AffiliateModel.AffiliatedCustomerModel { Id = customer.Id, Email = customer.Email, @@ -340,16 +348,23 @@ public ActionResult AffiliatedCustomerList(int affiliateId, GridCommand command) FullName = customer.GetFullName() }; - return customerModel; - }), - Total = customers.TotalCount - }; + return customerModel; + }); + model.Total = customers.TotalCount; + } + else + { + model.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } return new JsonResult { Data = model }; } + #endregion } } diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/BlogController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/BlogController.cs index 98d4a868c4..f0883628b1 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/BlogController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/BlogController.cs @@ -105,29 +105,37 @@ public ActionResult List() [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult List(GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageBlog)) - return AccessDeniedView(); + var model = new GridModel(); + + if (_permissionService.Authorize(StandardPermissionProvider.ManageBlog)) + { + var blogPosts = _blogService.GetAllBlogPosts(0, 0, null, null, command.Page - 1, command.PageSize, true); + + model.Data = blogPosts.Select(x => + { + var m = x.ToModel(); + if (x.StartDateUtc.HasValue) + m.StartDate = _dateTimeHelper.ConvertToUserTime(x.StartDateUtc.Value, DateTimeKind.Utc); + if (x.EndDateUtc.HasValue) + m.EndDate = _dateTimeHelper.ConvertToUserTime(x.EndDateUtc.Value, DateTimeKind.Utc); + m.CreatedOn = _dateTimeHelper.ConvertToUserTime(x.CreatedOnUtc, DateTimeKind.Utc); + m.LanguageName = x.Language.Name; + m.Comments = x.ApprovedCommentCount + x.NotApprovedCommentCount; + return m; + }); + + model.Total = blogPosts.TotalCount; + } + else + { + model.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } - var blogPosts = _blogService.GetAllBlogPosts(0, 0, null, null, command.Page - 1, command.PageSize, true); - var gridModel = new GridModel - { - Data = blogPosts.Select(x => - { - var m = x.ToModel(); - if (x.StartDateUtc.HasValue) - m.StartDate = _dateTimeHelper.ConvertToUserTime(x.StartDateUtc.Value, DateTimeKind.Utc); - if (x.EndDateUtc.HasValue) - m.EndDate = _dateTimeHelper.ConvertToUserTime(x.EndDateUtc.Value, DateTimeKind.Utc); - m.CreatedOn = _dateTimeHelper.ConvertToUserTime(x.CreatedOnUtc, DateTimeKind.Utc); - m.LanguageName = x.Language.Name; - m.Comments = x.ApprovedCommentCount + x.NotApprovedCommentCount; - return m; - }), - Total = blogPosts.TotalCount - }; return new JsonResult { - Data = gridModel + Data = model }; } @@ -269,71 +277,76 @@ public ActionResult Comments(int? filterByBlogPostId) [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult Comments(int? filterByBlogPostId, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageBlog)) - return AccessDeniedView(); + var model = new GridModel(); - IList comments; - if (filterByBlogPostId.HasValue) - { - //filter comments by blog - var blogPost = _blogService.GetBlogPostById(filterByBlogPostId.Value); - comments = blogPost.BlogComments.OrderBy(bc => bc.CreatedOnUtc).ToList(); - } - else - { - //load all blog comments - comments = _customerContentService.GetAllCustomerContent(0, null); - } + if (_permissionService.Authorize(StandardPermissionProvider.ManageBlog)) + { + IList comments; + if (filterByBlogPostId.HasValue) + { + //filter comments by blog + var blogPost = _blogService.GetBlogPostById(filterByBlogPostId.Value); + comments = blogPost.BlogComments.OrderBy(bc => bc.CreatedOnUtc).ToList(); + } + else + { + //load all blog comments + comments = _customerContentService.GetAllCustomerContent(0, null); + } - var gridModel = new GridModel - { - Data = comments.PagedForCommand(command).Select(blogComment => - { - var commentModel = new BlogCommentModel(); + model.Data = comments.PagedForCommand(command).Select(blogComment => + { + var commentModel = new BlogCommentModel(); var customer = _customerService.GetCustomerById(blogComment.CustomerId); - commentModel.Id = blogComment.Id; - commentModel.BlogPostId = blogComment.BlogPostId; - commentModel.BlogPostTitle = blogComment.BlogPost.Title; - commentModel.CustomerId = blogComment.CustomerId; - commentModel.IpAddress = blogComment.IpAddress; - commentModel.CreatedOn = _dateTimeHelper.ConvertToUserTime(blogComment.CreatedOnUtc, DateTimeKind.Utc); - commentModel.Comment = Core.Html.HtmlUtils.FormatText(blogComment.CommentText, false, true, false, false, false, false); + commentModel.Id = blogComment.Id; + commentModel.BlogPostId = blogComment.BlogPostId; + commentModel.BlogPostTitle = blogComment.BlogPost.Title; + commentModel.CustomerId = blogComment.CustomerId; + commentModel.IpAddress = blogComment.IpAddress; + commentModel.CreatedOn = _dateTimeHelper.ConvertToUserTime(blogComment.CreatedOnUtc, DateTimeKind.Utc); + commentModel.Comment = Core.Html.HtmlUtils.FormatText(blogComment.CommentText, false, true, false, false, false, false); if (customer == null) commentModel.CustomerName = "".NaIfEmpty(); else commentModel.CustomerName = customer.GetFullName(); - return commentModel; - }), - Total = comments.Count, - }; + return commentModel; + }); + + model.Total = comments.Count; + } + else + { + model.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } + return new JsonResult { - Data = gridModel + Data = model }; } [GridAction(EnableCustomBinding = true)] public ActionResult CommentDelete(int? filterByBlogPostId, int id, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageBlog)) - return AccessDeniedView(); + if (_permissionService.Authorize(StandardPermissionProvider.ManageBlog)) + { + var comment = _customerContentService.GetCustomerContentById(id) as BlogComment; - var comment = _customerContentService.GetCustomerContentById(id) as BlogComment; - if (comment == null) - throw new ArgumentException("No comment found with the specified id"); + var blogPost = comment.BlogPost; + _customerContentService.DeleteCustomerContent(comment); - var blogPost = comment.BlogPost; - _customerContentService.DeleteCustomerContent(comment); - //update totals - _blogService.UpdateCommentTotals(blogPost); + //update totals + _blogService.UpdateCommentTotals(blogPost); + } return Comments(filterByBlogPostId, command); } - #endregion } } diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/CampaignController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/CampaignController.cs index 7b3b290fd9..51f11cd40c 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/CampaignController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/CampaignController.cs @@ -88,24 +88,31 @@ public ActionResult List() [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult List(GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCampaigns)) - return AccessDeniedView(); + var model = new GridModel(); - var campaigns = _campaignService.GetAllCampaigns(); - var gridModel = new GridModel - { - Data = campaigns.Select(x => - { - var model = x.ToModel(); - model.CreatedOn = _dateTimeHelper.ConvertToUserTime(x.CreatedOnUtc, DateTimeKind.Utc); - return model; - }), - Total = campaigns.Count - }; + if (_permissionService.Authorize(StandardPermissionProvider.ManageCampaigns)) + { + var campaigns = _campaignService.GetAllCampaigns(); + + model.Data = campaigns.Select(x => + { + var m = x.ToModel(); + m.CreatedOn = _dateTimeHelper.ConvertToUserTime(x.CreatedOnUtc, DateTimeKind.Utc); + return m; + }); + + model.Total = campaigns.Count; + } + else + { + model.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } return new JsonResult { - Data = gridModel + Data = model }; } diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/CategoryController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/CategoryController.cs index c8b714dfab..05822a9c17 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/CategoryController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/CategoryController.cs @@ -285,24 +285,30 @@ public ActionResult List() [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult List(GridCommand command, CategoryListModel model) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); + var gridModel = new GridModel(); - var categories = _categoryService.GetAllCategories(model.SearchCategoryName, command.Page - 1, command.PageSize, true, model.SearchAlias, true, false, model.SearchStoreId); - var mappedCategories = categories.ToDictionary(x => x.Id); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + var categories = _categoryService.GetAllCategories(model.SearchCategoryName, command.Page - 1, command.PageSize, true, model.SearchAlias, true, false, model.SearchStoreId); + var mappedCategories = categories.ToDictionary(x => x.Id); - var gridModel = new GridModel - { - Data = categories.Select(x => - { - var categoryModel = x.ToModel(); - categoryModel.Breadcrumb = x.GetCategoryBreadCrumb(_categoryService, mappedCategories); - return categoryModel; - }), - Total = categories.TotalCount - }; + gridModel.Data = categories.Select(x => + { + var categoryModel = x.ToModel(); + categoryModel.Breadcrumb = x.GetCategoryBreadCrumb(_categoryService, mappedCategories); + return categoryModel; + }); + + gridModel.Total = categories.TotalCount; + } + else + { + gridModel.Data = Enumerable.Empty(); - return new JsonResult + NotifyAccessDenied(); + } + + return new JsonResult { Data = gridModel }; @@ -758,17 +764,16 @@ public ActionResult Delete(int id, string deleteType) [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult ProductList(GridCommand command, int categoryId) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); - - var productCategories = _categoryService.GetProductCategoriesByCategoryId(categoryId, command.Page - 1, command.PageSize, true); + var model = new GridModel(); - var products = _productService.GetProductsByIds(productCategories.Select(x => x.ProductId).ToArray()); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + var productCategories = _categoryService.GetProductCategoriesByCategoryId(categoryId, command.Page - 1, command.PageSize, true); - var model = new GridModel - { - Data = productCategories.Select(x => - { + var products = _productService.GetProductsByIds(productCategories.Select(x => x.ProductId).ToArray()); + + model.Data = productCategories.Select(x => + { var productModel = new CategoryModel.CategoryProductModel { Id = x.Id, @@ -788,13 +793,20 @@ public ActionResult ProductList(GridCommand command, int categoryId) productModel.ProductTypeLabelHint = product.ProductTypeLabelHint; productModel.Published = product.Published; } - + return productModel; - }), - Total = productCategories.TotalCount - }; + }); + + model.Total = productCategories.TotalCount; + } + else + { + model.Data = Enumerable.Empty(); - return new JsonResult + NotifyAccessDenied(); + } + + return new JsonResult { Data = model }; @@ -803,34 +815,32 @@ public ActionResult ProductList(GridCommand command, int categoryId) [GridAction(EnableCustomBinding = true)] public ActionResult ProductUpdate(GridCommand command, CategoryModel.CategoryProductModel model) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + var productCategory = _categoryService.GetProductCategoryById(model.Id); - var productCategory = _categoryService.GetProductCategoryById(model.Id); - if (productCategory == null) - throw new ArgumentException("No product category mapping found with the specified id"); + productCategory.IsFeaturedProduct = model.IsFeaturedProduct; + productCategory.DisplayOrder = model.DisplayOrder1; - productCategory.IsFeaturedProduct = model.IsFeaturedProduct; - productCategory.DisplayOrder = model.DisplayOrder1; - _categoryService.UpdateProductCategory(productCategory); + _categoryService.UpdateProductCategory(productCategory); + } - return ProductList(command, productCategory.CategoryId); + return ProductList(command, model.Id); } [GridAction(EnableCustomBinding = true)] public ActionResult ProductDelete(int id, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + var productCategory = _categoryService.GetProductCategoryById(id); - var productCategory = _categoryService.GetProductCategoryById(id); - if (productCategory == null) - throw new ArgumentException("No product category mapping found with the specified id"); + var categoryId = productCategory.CategoryId; - var categoryId = productCategory.CategoryId; - _categoryService.DeleteProductCategory(productCategory); + _categoryService.DeleteProductCategory(productCategory); + } - return ProductList(command, categoryId); + return ProductList(command, id); } public ActionResult ProductAddPopup(int categoryId) @@ -838,7 +848,6 @@ public ActionResult ProductAddPopup(int categoryId) if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) return AccessDeniedView(); - var ctx = new ProductSearchContext(); ctx.LanguageId = _workContext.WorkingLanguage.Id; ctx.OrderBy = ProductSortingEnum.Position; @@ -864,16 +873,18 @@ public ActionResult ProductAddPopup(int categoryId) var mappedCategories = allCategories.ToDictionary(x => x.Id); foreach (var c in allCategories) { - model.AvailableCategories.Add(new SelectListItem() { Text = c.GetCategoryNameWithPrefix(_categoryService, mappedCategories), Value = c.Id.ToString() }); + model.AvailableCategories.Add(new SelectListItem { Text = c.GetCategoryNameWithPrefix(_categoryService, mappedCategories), Value = c.Id.ToString() }); } - //manufacturers - foreach (var m in _manufacturerService.GetAllManufacturers(true)) - model.AvailableManufacturers.Add(new SelectListItem() { Text = m.Name, Value = m.Id.ToString() }); + //manufacturers + foreach (var m in _manufacturerService.GetAllManufacturers(true)) + { + model.AvailableManufacturers.Add(new SelectListItem { Text = m.Name, Value = m.Id.ToString() }); + } //product types model.AvailableProductTypes = ProductType.SimpleProduct.ToSelectList(false).ToList(); - model.AvailableProductTypes.Insert(0, new SelectListItem() { Text = _localizationService.GetResource("Admin.Common.All"), Value = "0" }); + model.AvailableProductTypes.Insert(0, new SelectListItem { Text = _localizationService.GetResource("Admin.Common.All"), Value = "0" }); return View(model); } @@ -881,35 +892,44 @@ public ActionResult ProductAddPopup(int categoryId) [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult ProductAddPopupList(GridCommand command, CategoryModel.AddCategoryProductModel model) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); + var gridModel = new GridModel(); - var gridModel = new GridModel(); - var ctx = new ProductSearchContext(); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + var ctx = new ProductSearchContext(); - if (model.SearchCategoryId > 0) - ctx.CategoryIds.Add(model.SearchCategoryId); + if (model.SearchCategoryId > 0) + ctx.CategoryIds.Add(model.SearchCategoryId); - ctx.ManufacturerId = model.SearchManufacturerId; - ctx.Keywords = model.SearchProductName; - ctx.LanguageId = _workContext.WorkingLanguage.Id; - ctx.OrderBy = ProductSortingEnum.Position; - ctx.PageIndex = command.Page - 1; - ctx.PageSize = command.PageSize; - ctx.ShowHidden = true; - ctx.ProductType = model.SearchProductTypeId > 0 ? (ProductType?)model.SearchProductTypeId : null; + ctx.ManufacturerId = model.SearchManufacturerId; + ctx.Keywords = model.SearchProductName; + ctx.LanguageId = _workContext.WorkingLanguage.Id; + ctx.OrderBy = ProductSortingEnum.Position; + ctx.PageIndex = command.Page - 1; + ctx.PageSize = command.PageSize; + ctx.ShowHidden = true; + ctx.ProductType = model.SearchProductTypeId > 0 ? (ProductType?)model.SearchProductTypeId : null; - var products = _productService.SearchProducts(ctx); - gridModel.Data = products.Select(x => + var products = _productService.SearchProducts(ctx); + + gridModel.Data = products.Select(x => + { + var productModel = x.ToModel(); + productModel.ProductTypeName = x.GetProductTypeLabel(_localizationService); + + return productModel; + }); + + gridModel.Total = products.TotalCount; + } + else { - var productModel = x.ToModel(); - productModel.ProductTypeName = x.GetProductTypeLabel(_localizationService); + gridModel.Data = Enumerable.Empty(); - return productModel; - }); + NotifyAccessDenied(); + } - gridModel.Total = products.TotalCount; - return new JsonResult + return new JsonResult { Data = gridModel }; diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/CheckoutAttributeController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/CheckoutAttributeController.cs index 78170d9674..4ac32d8493 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/CheckoutAttributeController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/CheckoutAttributeController.cs @@ -104,7 +104,6 @@ private void PrepareCheckoutAttributeModel(CheckoutAttributeModel model, Checkou #region Checkout attributes - //list public ActionResult Index() { return RedirectToAction("List"); @@ -121,23 +120,31 @@ public ActionResult List() [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult List(GridCommand command) { - if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); + var model = new GridModel(); - var checkoutAttributes = _checkoutAttributeService.GetAllCheckoutAttributes(true); - var gridModel = new GridModel - { - Data = checkoutAttributes.Select(x => - { - var caModel = x.ToModel(); - caModel.AttributeControlTypeName = x.AttributeControlType.GetLocalizedEnum(_services.Localization, _services.WorkContext); - return caModel; - }), - Total = checkoutAttributes.Count() - }; - return new JsonResult + if (_services.Permissions.Authorize(StandardPermissionProvider.ManageCatalog)) + { + var checkoutAttributes = _checkoutAttributeService.GetAllCheckoutAttributes(true); + + model.Data = checkoutAttributes.Select(x => + { + var caModel = x.ToModel(); + caModel.AttributeControlTypeName = x.AttributeControlType.GetLocalizedEnum(_services.Localization, _services.WorkContext); + return caModel; + }); + + model.Total = checkoutAttributes.Count(); + } + else + { + model.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } + + return new JsonResult { - Data = gridModel + Data = model }; } @@ -254,31 +261,29 @@ public ActionResult DeleteConfirmed(int id) #region Checkout attribute values - //list [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult ValueList(int checkoutAttributeId, GridCommand command) { - if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); + var model = new GridModel(); - var values = _checkoutAttributeService.GetCheckoutAttributeValues(checkoutAttributeId); - var gridModel = new GridModel - { - Data = values.Select(x => - { - var model = x.ToModel(); - //locales - //AddLocales(_languageService, model.Locales, (locale, languageId) => - //{ - // locale.Name = x.GetLocalized(y => y.Name, languageId, false, false); - //}); - return model; - }), - Total = values.Count() - }; - return new JsonResult + if (_services.Permissions.Authorize(StandardPermissionProvider.ManageCatalog)) + { + var values = _checkoutAttributeService.GetCheckoutAttributeValues(checkoutAttributeId); + + model.Data = values.Select(x => x.ToModel()); + + model.Total = values.Count(); + } + else + { + model.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } + + return new JsonResult { - Data = gridModel + Data = model }; } @@ -384,22 +389,19 @@ public ActionResult ValueEditPopup(string btnId, string formId, CheckoutAttribut return View(model); } - //delete [GridAction(EnableCustomBinding = true)] public ActionResult ValueDelete(int valueId, int checkoutAttributeId, GridCommand command) { - if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); + if (_services.Permissions.Authorize(StandardPermissionProvider.ManageCatalog)) + { + var cav = _checkoutAttributeService.GetCheckoutAttributeValueById(valueId); - var cav = _checkoutAttributeService.GetCheckoutAttributeValueById(valueId); - if (cav == null) - throw new ArgumentException("No checkout attribute value found with the specified id"); - _checkoutAttributeService.DeleteCheckoutAttributeValue(cav); + _checkoutAttributeService.DeleteCheckoutAttributeValue(cav); + } return ValueList(checkoutAttributeId, command); } - #endregion } } diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/CommonController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/CommonController.cs index ce08f8803f..5127d27256 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/CommonController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/CommonController.cs @@ -1034,35 +1034,43 @@ public ActionResult GenericAttributes(string entityName, int entityId) [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult GenericAttributesSelect(string entityName, int entityId, GridCommand command) { - if (!_services.Permissions.Authorize(StandardPermissionProvider.AccessAdminPanel)) - return AccessDeniedView(); + var model = new GridModel(); var storeId = _services.StoreContext.CurrentStore.Id; - ViewBag.StoreId = storeId; + ViewBag.StoreId = storeId; - var model = new List(); - if (entityName.HasValue() && entityId > 0) - { - var attributes = _genericAttributeService.GetAttributesForEntity(entityId, entityName); - var query = from attr in attributes - where attr.StoreId == storeId || attr.StoreId == 0 - select new GenericAttributeModel - { - Id = attr.Id, - EntityId = attr.EntityId, - EntityName = attr.KeyGroup, - Key = attr.Key, - Value = attr.Value - }; - model.AddRange(query); - } + if (_services.Permissions.Authorize(StandardPermissionProvider.AccessAdminPanel)) + { + if (entityName.HasValue() && entityId > 0) + { + var attributes = _genericAttributeService.GetAttributesForEntity(entityId, entityName); + model.Data = attributes + .Where(x => x.StoreId == storeId || x.StoreId == 0) + .Select(x => new GenericAttributeModel + { + Id = x.Id, + EntityId = x.EntityId, + EntityName = x.KeyGroup, + Key = x.Key, + Value = x.Value + }) + .ToList(); + + model.Total = model.Data.Count(); + } + else + { + model.Data = Enumerable.Empty(); + } + } + else + { + model.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } - var result = new GridModel - { - Data = model, - Total = model.Count - }; return new JsonResult { Data = model @@ -1072,38 +1080,36 @@ public ActionResult GenericAttributesSelect(string entityName, int entityId, Gri [GridAction(EnableCustomBinding = true)] public ActionResult GenericAttributeAdd(GenericAttributeModel model, GridCommand command) { - if (!_services.Permissions.Authorize(StandardPermissionProvider.AccessAdminPanel)) - return AccessDeniedView(); + if (_services.Permissions.Authorize(StandardPermissionProvider.AccessAdminPanel)) + { + model.Key = model.Key.TrimSafe(); + model.Value = model.Value.TrimSafe(); - model.Key = model.Key.TrimSafe(); - model.Value = model.Value.TrimSafe(); + if (!ModelState.IsValid) + { + var modelStateErrorMessages = this.ModelState.Values.SelectMany(x => x.Errors).Select(x => x.ErrorMessage); + return Content(modelStateErrorMessages.FirstOrDefault()); + } - if (!ModelState.IsValid) - { - // display the first model error - var modelStateErrorMessages = this.ModelState.Values.SelectMany(x => x.Errors).Select(x => x.ErrorMessage); - return Content(modelStateErrorMessages.FirstOrDefault()); - } + var storeId = _services.StoreContext.CurrentStore.Id; - var storeId = _services.StoreContext.CurrentStore.Id; - - var attr = _genericAttributeService.GetAttribute(model.EntityName, model.EntityId, model.Key, storeId); - if (attr == null) - { - var ga = new GenericAttribute - { - StoreId = storeId, - KeyGroup = model.EntityName, - EntityId = model.EntityId, - Key = model.Key, - Value = model.Value - }; - _genericAttributeService.InsertAttribute(ga); - } - else - { - return Content(string.Format(_localizationService.GetResource("Admin.Common.GenericAttributes.NameAlreadyExists"), model.Key)); - } + var attr = _genericAttributeService.GetAttribute(model.EntityName, model.EntityId, model.Key, storeId); + if (attr == null) + { + _genericAttributeService.InsertAttribute(new GenericAttribute + { + StoreId = storeId, + KeyGroup = model.EntityName, + EntityId = model.EntityId, + Key = model.Key, + Value = model.Value + }); + } + else + { + return Content(T("Admin.Common.GenericAttributes.NameAlreadyExists", model.Key)); + } + } return GenericAttributesSelect(model.EntityName, model.EntityId, command); } @@ -1111,38 +1117,38 @@ public ActionResult GenericAttributeAdd(GenericAttributeModel model, GridCommand [GridAction(EnableCustomBinding = true)] public ActionResult GenericAttributeUpdate(GenericAttributeModel model, GridCommand command) { - if (!_services.Permissions.Authorize(StandardPermissionProvider.AccessAdminPanel)) - return AccessDeniedView(); + if (_services.Permissions.Authorize(StandardPermissionProvider.AccessAdminPanel)) + { + model.Key = model.Key.TrimSafe(); + model.Value = model.Value.TrimSafe(); - model.Key = model.Key.TrimSafe(); - model.Value = model.Value.TrimSafe(); + if (!ModelState.IsValid) + { + var modelStateErrorMessages = this.ModelState.Values.SelectMany(x => x.Errors).Select(x => x.ErrorMessage); + return Content(modelStateErrorMessages.FirstOrDefault()); + } - if (!ModelState.IsValid) - { - // display the first model error - var modelStateErrorMessages = this.ModelState.Values.SelectMany(x => x.Errors).Select(x => x.ErrorMessage); - return Content(modelStateErrorMessages.FirstOrDefault()); - } + var storeId = _services.StoreContext.CurrentStore.Id; - var storeId = _services.StoreContext.CurrentStore.Id; + var attr = _genericAttributeService.GetAttributeById(model.Id); + // if the key changed, ensure it isn't being used by another attribute + if (!attr.Key.IsCaseInsensitiveEqual(model.Key)) + { + var attr2 = _genericAttributeService.GetAttributesForEntity(model.EntityId, model.EntityName) + .Where(x => x.StoreId == storeId && x.Key.Equals(model.Key, StringComparison.InvariantCultureIgnoreCase)) + .FirstOrDefault(); - var attr = _genericAttributeService.GetAttributeById(model.Id); - // if the key changed, ensure it isn't being used by another attribute - if (!attr.Key.IsCaseInsensitiveEqual(model.Key)) - { - var attr2 = _genericAttributeService.GetAttributesForEntity(model.EntityId, model.EntityName) - .Where(x => x.StoreId == storeId && x.Key.Equals(model.Key, StringComparison.InvariantCultureIgnoreCase)) - .FirstOrDefault(); - if (attr2 != null && attr2.Id != attr.Id) - { - return Content(string.Format(_localizationService.GetResource("Admin.Common.GenericAttributes.NameAlreadyExists"), model.Key)); - } - } + if (attr2 != null && attr2.Id != attr.Id) + { + return Content(T("Admin.Common.GenericAttributes.NameAlreadyExists", model.Key)); + } + } - attr.Key = model.Key; - attr.Value = model.Value; + attr.Key = model.Key; + attr.Value = model.Value; - _genericAttributeService.UpdateAttribute(attr); + _genericAttributeService.UpdateAttribute(attr); + } return GenericAttributesSelect(model.EntityName, model.EntityId, command); } @@ -1150,17 +1156,12 @@ public ActionResult GenericAttributeUpdate(GenericAttributeModel model, GridComm [GridAction(EnableCustomBinding = true)] public ActionResult GenericAttributeDelete(int id, GridCommand command) { - if (!_services.Permissions.Authorize(StandardPermissionProvider.AccessAdminPanel)) - return AccessDeniedView(); - var attr = _genericAttributeService.GetAttributeById(id); - if (attr == null) - { - throw new System.Web.HttpException(404, "No resource found with the specified id"); - } - - _genericAttributeService.DeleteAttribute(attr); + if (_services.Permissions.Authorize(StandardPermissionProvider.AccessAdminPanel)) + { + _genericAttributeService.DeleteAttribute(attr); + } return GenericAttributesSelect(attr.KeyGroup, attr.EntityId, command); } diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/CountryController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/CountryController.cs index bf67df0dae..3a4d573b43 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/CountryController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/CountryController.cs @@ -304,17 +304,22 @@ public ActionResult DeleteConfirmed(int id) [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult States(int countryId, GridCommand command) { - if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageCountries)) - return AccessDeniedView(); + var model = new GridModel(); - var states = _stateProvinceService.GetStateProvincesByCountryId(countryId, true) - .Select(x => x.ToModel()); + if (_services.Permissions.Authorize(StandardPermissionProvider.ManageCountries)) + { + var states = _stateProvinceService.GetStateProvincesByCountryId(countryId, true) + .Select(x => x.ToModel()); - var model = new GridModel - { - Data = states, - Total = states.Count() - }; + model.Data = states; + model.Total = states.Count(); + } + else + { + model.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } return new JsonResult { @@ -417,18 +422,18 @@ public ActionResult StateEditPopup(string btnId, string formId, StateProvinceMod [GridAction(EnableCustomBinding = true)] public ActionResult StateDelete(int id, GridCommand command) { - if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageCountries)) - return AccessDeniedView(); - - var state = _stateProvinceService.GetStateProvinceById(id); - if (state == null) - throw new ArgumentException("No state found with the specified id"); + var state = _stateProvinceService.GetStateProvinceById(id); + var countryId = state.CountryId; - if (_addressService.GetAddressTotalByStateProvinceId(state.Id) > 0) - return Content(T("Admin.Configuration.Countries.States.CantDeleteWithAddresses")); + if (_services.Permissions.Authorize(StandardPermissionProvider.ManageCountries)) + { + if (_addressService.GetAddressTotalByStateProvinceId(state.Id) > 0) + { + return Content(T("Admin.Configuration.Countries.States.CantDeleteWithAddresses")); + } - int countryId = state.CountryId; - _stateProvinceService.DeleteStateProvince(state); + _stateProvinceService.DeleteStateProvince(state); + } return States(countryId, command); } diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/CurrencyController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/CurrencyController.cs index 181071a2d2..e20b59013c 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/CurrencyController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/CurrencyController.cs @@ -239,18 +239,25 @@ public ActionResult Save(FormCollection formValues) [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult List(GridCommand command) { - if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageCurrencies)) - return AccessDeniedView(); + var model = new GridModel(); + + if (_services.Permissions.Authorize(StandardPermissionProvider.ManageCurrencies)) + { + var currencies = _currencyService.GetAllCurrencies(true); + + model.Data = currencies.Select(x => x.ToModel()); + model.Total = currencies.Count(); + } + else + { + model.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } - var currencies = _currencyService.GetAllCurrencies(true); - var gridModel = new GridModel - { - Data = currencies.Select(x => x.ToModel()), - Total = currencies.Count() - }; return new JsonResult { - Data = gridModel + Data = model }; } diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/CustomerController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/CustomerController.cs index 892bbaf5c6..0a91c9860f 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/CustomerController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/CustomerController.cs @@ -396,28 +396,37 @@ public ActionResult List() [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult CustomerList(GridCommand command, CustomerListModel model, [ModelBinderAttribute(typeof(CommaSeparatedModelBinder))] int[] searchCustomerRoleIds) { - //we use own own binder for searchCustomerRoleIds property - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCustomers)) - return AccessDeniedView(); + // we use own own binder for searchCustomerRoleIds property + var gridModel = new GridModel(); + + if (_permissionService.Authorize(StandardPermissionProvider.ManageCustomers)) + { + var searchDayOfBirth = 0; + var searchMonthOfBirth = 0; + + if (!String.IsNullOrWhiteSpace(model.SearchDayOfBirth)) + searchDayOfBirth = Convert.ToInt32(model.SearchDayOfBirth); + + if (!String.IsNullOrWhiteSpace(model.SearchMonthOfBirth)) + searchMonthOfBirth = Convert.ToInt32(model.SearchMonthOfBirth); + + var customers = _customerService.GetAllCustomers(null, null, + searchCustomerRoleIds, model.SearchEmail, model.SearchUsername, + model.SearchFirstName, model.SearchLastName, + searchDayOfBirth, searchMonthOfBirth, + model.SearchCompany, model.SearchPhone, model.SearchZipPostalCode, + false, null, command.Page - 1, command.PageSize); + + gridModel.Data = customers.Select(PrepareCustomerModelForList); + gridModel.Total = customers.TotalCount; + } + else + { + gridModel.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } - var searchDayOfBirth = 0; - int searchMonthOfBirth = 0; - if (!String.IsNullOrWhiteSpace(model.SearchDayOfBirth)) - searchDayOfBirth = Convert.ToInt32(model.SearchDayOfBirth); - if (!String.IsNullOrWhiteSpace(model.SearchMonthOfBirth)) - searchMonthOfBirth = Convert.ToInt32(model.SearchMonthOfBirth); - - var customers = _customerService.GetAllCustomers(null, null, - searchCustomerRoleIds, model.SearchEmail, model.SearchUsername, - model.SearchFirstName, model.SearchLastName, - searchDayOfBirth, searchMonthOfBirth, - model.SearchCompany, model.SearchPhone, model.SearchZipPostalCode, - false, null, command.Page - 1, command.PageSize); - var gridModel = new GridModel - { - Data = customers.Select(PrepareCustomerModelForList), - Total = customers.TotalCount - }; return new JsonResult { Data = gridModel @@ -1519,17 +1528,15 @@ public ActionResult AddressEdit(CustomerAddressModel model) [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult OrderList(int customerId, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCustomers)) - return AccessDeniedView(); + var model = new GridModel(); - var orders = _orderService.SearchOrders(0, customerId, - null, null, null, null, null, null, null, null, 0, int.MaxValue); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCustomers)) + { + var orders = _orderService.SearchOrders(0, customerId, null, null, null, null, null, null, null, null, 0, int.MaxValue); - var model = new GridModel - { - Data = orders.PagedForCommand(command) - .Select(order => - { + model.Data = orders.PagedForCommand(command) + .Select(order => + { var store = _storeService.GetStoreById(order.StoreId); var orderModel = new CustomerModel.OrderModel() { @@ -1538,13 +1545,20 @@ public ActionResult OrderList(int customerId, GridCommand command) PaymentStatus = order.PaymentStatus.GetLocalizedEnum(_localizationService, _workContext), ShippingStatus = order.ShippingStatus.GetLocalizedEnum(_localizationService, _workContext), OrderTotal = _priceFormatter.FormatPrice(order.OrderTotal, true, false), - StoreName = store != null ? store.Name : "Unknown", + StoreName = store != null ? store.Name : "".NaIfEmpty(), CreatedOn = _dateTimeHelper.ConvertToUserTime(order.CreatedOnUtc, DateTimeKind.Utc), }; - return orderModel; - }), - Total = orders.Count - }; + return orderModel; + }); + + model.Total = orders.Count; + } + else + { + model.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } return new JsonResult { @@ -1596,9 +1610,8 @@ public ActionResult ReportBestCustomersByOrderTotalList(GridCommand command, Bes PaymentStatus? paymentStatus = model.PaymentStatusId > 0 ? (PaymentStatus?)(model.PaymentStatusId) : null; ShippingStatus? shippingStatus = model.ShippingStatusId > 0 ? (ShippingStatus?)(model.ShippingStatusId) : null; + var items = _customerReportService.GetBestCustomersReport(startDateValue, endDateValue, orderStatus, paymentStatus, shippingStatus, 1); - var items = _customerReportService.GetBestCustomersReport(startDateValue, endDateValue, - orderStatus, paymentStatus, shippingStatus, 1); var gridModel = new GridModel { Data = items.Select(x => @@ -1609,23 +1622,25 @@ public ActionResult ReportBestCustomersByOrderTotalList(GridCommand command, Bes OrderTotal = _priceFormatter.FormatPrice(x.OrderTotal, true, false), OrderCount = x.OrderCount, }; + var customer = _customerService.GetCustomerById(x.CustomerId); if (customer != null) { - m.CustomerName = customer.IsGuest() - ? _localizationService.GetResource("Admin.Customers.Guest") - : customer.Email; + m.CustomerName = customer.IsGuest() ? T("Admin.Customers.Guest").Text : customer.Email; } + return m; }), Total = items.Count }; + return new JsonResult { Data = gridModel }; } - [GridAction(EnableCustomBinding = true)] + + [GridAction(EnableCustomBinding = true)] public ActionResult ReportBestCustomersByNumberOfOrdersList(GridCommand command, BestCustomersReportModel model) { DateTime? startDateValue = (model.StartDate == null) ? null @@ -1638,26 +1653,25 @@ public ActionResult ReportBestCustomersByNumberOfOrdersList(GridCommand command, PaymentStatus? paymentStatus = model.PaymentStatusId > 0 ? (PaymentStatus?)(model.PaymentStatusId) : null; ShippingStatus? shippingStatus = model.ShippingStatusId > 0 ? (ShippingStatus?)(model.ShippingStatusId) : null; + var items = _customerReportService.GetBestCustomersReport(startDateValue, endDateValue, orderStatus, paymentStatus, shippingStatus, 2); - var items = _customerReportService.GetBestCustomersReport(startDateValue, endDateValue, - orderStatus, paymentStatus, shippingStatus, 2); var gridModel = new GridModel { Data = items.Select(x => { - var m = new BestCustomerReportLineModel() + var m = new BestCustomerReportLineModel { CustomerId = x.CustomerId, OrderTotal = _priceFormatter.FormatPrice(x.OrderTotal, true, false), OrderCount = x.OrderCount, }; + var customer = _customerService.GetCustomerById(x.CustomerId); if (customer != null) { - m.CustomerName = customer.IsGuest() - ? _localizationService.GetResource("Admin.Customers.Guest") - : customer.Email; + m.CustomerName = customer.IsGuest() ? T("Admin.Customers.Guest").Text : customer.Email; } + return m; }), Total = items.Count @@ -1674,15 +1688,18 @@ public ActionResult ReportRegisteredCustomers() var model = GetReportRegisteredCustomersModel(); return PartialView(model); } - [GridAction(EnableCustomBinding = true)] + + [GridAction(EnableCustomBinding = true)] public ActionResult ReportRegisteredCustomersList(GridCommand command) { var model = GetReportRegisteredCustomersModel(); - var gridModel = new GridModel + + var gridModel = new GridModel { Data = model, Total = model.Count }; + return new JsonResult { Data = gridModel @@ -1699,16 +1716,17 @@ public ActionResult GetCartList(int customerId, int cartTypeId) var customer = _customerService.GetCustomerById(customerId); var cart = customer.GetCartItems((ShoppingCartType)cartTypeId); - var gridModel = new GridModel() + var gridModel = new GridModel { Data = cart.Select(sci => { decimal taxRate; var store = _storeService.GetStoreById(sci.Item.StoreId); - var sciModel = new ShoppingCartItemModel() + + var sciModel = new ShoppingCartItemModel { Id = sci.Item.Id, - Store = store != null ? store.Name : "Unknown", + Store = store != null ? store.Name : "".NaIfEmpty(), ProductId = sci.Item.ProductId, Quantity = sci.Item.Quantity, ProductName = sci.Item.Product.Name, @@ -1722,6 +1740,7 @@ public ActionResult GetCartList(int customerId, int cartTypeId) }), Total = cart.Count }; + return new JsonResult { Data = gridModel @@ -1736,11 +1755,12 @@ public ActionResult GetCartList(int customerId, int cartTypeId) public JsonResult ListActivityLog(GridCommand command, int customerId) { var activityLog = _customerActivityService.GetAllActivities(null, null, customerId, 0, command.Page - 1, command.PageSize); + var gridModel = new GridModel { Data = activityLog.Select(x => { - var m = new CustomerModel.ActivityLogModel() + var m = new CustomerModel.ActivityLogModel { Id = x.Id, ActivityLogTypeName = x.ActivityLogType.Name, @@ -1748,11 +1768,11 @@ public JsonResult ListActivityLog(GridCommand command, int customerId) CreatedOn = _dateTimeHelper.ConvertToUserTime(x.CreatedOnUtc, DateTimeKind.Utc) }; return m; - }), Total = activityLog.TotalCount }; - return new JsonResult { Data = gridModel }; ; + + return new JsonResult { Data = gridModel }; } #endregion diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/CustomerRoleController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/CustomerRoleController.cs index 7cc7fa5575..6bb2d10b47 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/CustomerRoleController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/CustomerRoleController.cs @@ -102,18 +102,25 @@ public ActionResult List() [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult List(GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCustomerRoles)) - return AccessDeniedView(); - - var customerRoles = _customerService.GetAllCustomerRoles(true); - var gridModel = new GridModel + var model = new GridModel(); + + if (_permissionService.Authorize(StandardPermissionProvider.ManageCustomerRoles)) { - Data = customerRoles.Select(x => x.ToModel()), - Total = customerRoles.Count() - }; + var customerRoles = _customerService.GetAllCustomerRoles(true); + + model.Data = customerRoles.Select(x => x.ToModel()); + model.Total = customerRoles.Count(); + } + else + { + model.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } + return new JsonResult { - Data = gridModel + Data = model }; } diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/DiscountController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/DiscountController.cs index 6e18b8ec06..c9ab6e4496 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/DiscountController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/DiscountController.cs @@ -138,7 +138,6 @@ private void PrepareDiscountModel(DiscountModel model, Discount discount) #region Discounts - //list public ActionResult Index() { return RedirectToAction("List"); @@ -161,22 +160,28 @@ public ActionResult List() [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult List(GridCommand command) { - if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageDiscounts)) - return AccessDeniedView(); + var model = new GridModel(); + + if (_services.Permissions.Authorize(StandardPermissionProvider.ManageDiscounts)) + { + var discounts = _discountService.GetAllDiscounts(null, null, true); + + model.Data = discounts.Select(x => x.ToModel()); + model.Total = discounts.Count(); + } + else + { + model.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } - var discounts = _discountService.GetAllDiscounts(null, null, true); - var gridModel = new GridModel - { - Data = discounts.Select(x => x.ToModel()), - Total = discounts.Count() - }; return new JsonResult { - Data = gridModel + Data = model }; } - //create public ActionResult Create() { if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageDiscounts)) @@ -212,7 +217,6 @@ public ActionResult Create(DiscountModel model, bool continueEditing) return View(model); } - //edit public ActionResult Edit(int id) { if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageDiscounts)) @@ -281,7 +285,6 @@ public ActionResult Edit(DiscountModel model, bool continueEditing) return View(model); } - //delete [HttpPost, ActionName("Delete")] public ActionResult DeleteConfirmed(int id) { @@ -386,28 +389,31 @@ public ActionResult DeleteDiscountRequirement(int discountRequirementId, int dis [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult UsageHistoryList(int discountId, GridCommand command) { - if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageDiscounts)) - return AccessDeniedView(); + var model = new GridModel(); - var discount = _discountService.GetDiscountById(discountId); - if (discount == null) - throw new ArgumentException("No discount found with the specified id"); + if (_services.Permissions.Authorize(StandardPermissionProvider.ManageDiscounts)) + { + var discount = _discountService.GetDiscountById(discountId); + + var discountHistories = _discountService.GetAllDiscountUsageHistory(discount.Id, null, command.Page - 1, command.PageSize); + + model.Data = discountHistories.Select(x => new DiscountModel.DiscountUsageHistoryModel + { + Id = x.Id, + DiscountId = x.DiscountId, + OrderId = x.OrderId, + CreatedOn = _dateTimeHelper.ConvertToUserTime(x.CreatedOnUtc, DateTimeKind.Utc) + }); + + model.Total = discountHistories.TotalCount; + } + else + { + model.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } - var duh = _discountService.GetAllDiscountUsageHistory(discount.Id, null, command.Page - 1, command.PageSize); - var model = new GridModel - { - Data = duh.Select(x => - { - return new DiscountModel.DiscountUsageHistoryModel - { - Id = x.Id, - DiscountId = x.DiscountId, - OrderId = x.OrderId, - CreatedOn = _dateTimeHelper.ConvertToUserTime(x.CreatedOnUtc, DateTimeKind.Utc) - }; - }), - Total = duh.TotalCount - }; return new JsonResult { Data = model @@ -417,16 +423,13 @@ public ActionResult UsageHistoryList(int discountId, GridCommand command) [GridAction(EnableCustomBinding = true)] public ActionResult UsageHistoryDelete(int discountId, int id, GridCommand command) { - if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageDiscounts)) - return AccessDeniedView(); + if (_services.Permissions.Authorize(StandardPermissionProvider.ManageDiscounts)) + { + var discountHistory = _discountService.GetDiscountUsageHistoryById(id); + + _discountService.DeleteDiscountUsageHistory(discountHistory); + } - var discount = _discountService.GetDiscountById(discountId); - if (discount == null) - throw new ArgumentException("No discount found with the specified id"); - - var duh = _discountService.GetDiscountUsageHistoryById(id); - if (duh != null) - _discountService.DeleteDiscountUsageHistory(duh); return UsageHistoryList(discountId, command); } diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/EmailAccountController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/EmailAccountController.cs index c883d5f266..2586a826cb 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/EmailAccountController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/EmailAccountController.cs @@ -78,24 +78,32 @@ public ActionResult List(string id) [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult List(GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageEmailAccounts)) - return AccessDeniedView(); + var model = new GridModel(); - var emailAccountModels = _emailAccountService.GetAllEmailAccounts() - .Select(x => x.ToModel()) - .ToList(); - foreach (var eam in emailAccountModels) - eam.IsDefaultEmailAccount = eam.Id == _emailAccountSettings.DefaultEmailAccountId; + if (_permissionService.Authorize(StandardPermissionProvider.ManageEmailAccounts)) + { + var emailAccountModels = _emailAccountService.GetAllEmailAccounts() + .Select(x => x.ToModel()) + .ToList(); - var gridModel = new GridModel - { - Data = emailAccountModels, - Total = emailAccountModels.Count() - }; + foreach (var eam in emailAccountModels) + { + eam.IsDefaultEmailAccount = eam.Id == _emailAccountSettings.DefaultEmailAccountId; + } + + model.Data = emailAccountModels; + model.Total = emailAccountModels.Count(); + } + else + { + model.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } return new JsonResult { - Data = gridModel + Data = model }; } diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs index 2e719959ec..39579caa57 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/ExportController.cs @@ -823,11 +823,17 @@ public ActionResult Preview(int id) [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult PreviewList(GridCommand command, int id, int totalRecords) { + if (_services.Permissions.Authorize(StandardPermissionProvider.ManageExports)) + { + NotifyAccessDenied(); + + return new JsonResult { Data = Enumerable.Empty() }; + } + ExportProfile profile = null; Provider provider = null; - if (_services.Permissions.Authorize(StandardPermissionProvider.ManageExports) && - (profile = _exportService.GetExportProfileById(id)) != null && + if ((profile = _exportService.GetExportProfileById(id)) != null && (provider = _exportService.LoadProvider(profile.ProviderSystemName)) != null && !provider.Metadata.IsHidden) { @@ -984,7 +990,7 @@ public ActionResult PreviewList(GridCommand command, int id, int totalRecords) return new JsonResult { Data = gridData }; } - return new EmptyResult(); + return new JsonResult { Data = Enumerable.Empty() }; } [HttpPost] diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/GiftCardController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/GiftCardController.cs index ea3eff5cd1..f52756dd84 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/GiftCardController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/GiftCardController.cs @@ -94,27 +94,37 @@ public ActionResult List() [GridAction(EnableCustomBinding = true)] public ActionResult GiftCardList(GridCommand command, GiftCardListModel model) { - if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageGiftCards)) - return AccessDeniedView(); + var gridModel = new GridModel(); + + if (_services.Permissions.Authorize(StandardPermissionProvider.ManageGiftCards)) + { + bool? isGiftCardActivated = null; + + if (model.ActivatedId == 1) + isGiftCardActivated = true; + else if (model.ActivatedId == 2) + isGiftCardActivated = false; + + var giftCards = _giftCardService.GetAllGiftCards(null, null, null, isGiftCardActivated, model.CouponCode); + + gridModel.Data = giftCards.PagedForCommand(command).Select(x => + { + var m = x.ToModel(); + m.RemainingAmountStr = _priceFormatter.FormatPrice(x.GetGiftCardRemainingAmount(), true, false); + m.AmountStr = _priceFormatter.FormatPrice(x.Amount, true, false); + m.CreatedOn = _dateTimeHelper.ConvertToUserTime(x.CreatedOnUtc, DateTimeKind.Utc); + return m; + }); + + gridModel.Total = giftCards.Count(); + } + else + { + gridModel.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } - bool? isGiftCardActivated = null; - if (model.ActivatedId == 1) - isGiftCardActivated = true; - else if (model.ActivatedId == 2) - isGiftCardActivated = false; - var giftCards = _giftCardService.GetAllGiftCards(null, null, null, isGiftCardActivated, model.CouponCode); - var gridModel = new GridModel - { - Data = giftCards.PagedForCommand(command).Select(x => - { - var m = x.ToModel(); - m.RemainingAmountStr = _priceFormatter.FormatPrice(x.GetGiftCardRemainingAmount(), true, false); - m.AmountStr = _priceFormatter.FormatPrice(x.Amount, true, false); - m.CreatedOn = _dateTimeHelper.ConvertToUserTime(x.CreatedOnUtc, DateTimeKind.Utc); - return m; - }), - Total = giftCards.Count() - }; return new JsonResult { Data = gridModel @@ -274,46 +284,48 @@ public ActionResult DeleteConfirmed(int id) var giftCard = _giftCardService.GetGiftCardById(id); if (giftCard == null) - //No gift card found with the specified id return RedirectToAction("List"); _giftCardService.DeleteGiftCard(giftCard); - //activity log _customerActivityService.InsertActivity("DeleteGiftCard", _services.Localization.GetResource("ActivityLog.DeleteGiftCard"), giftCard.GiftCardCouponCode); NotifySuccess(_services.Localization.GetResource("Admin.GiftCards.Deleted")); return RedirectToAction("List"); } - //Gif card usage history [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult UsageHistoryList(int giftCardId, GridCommand command) { - if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageGiftCards)) - return AccessDeniedView(); - - var giftCard = _giftCardService.GetGiftCardById(giftCardId); - if (giftCard == null) - throw new ArgumentException("No gift card found with the specified id"); - - var usageHistoryModel = giftCard.GiftCardUsageHistory.OrderByDescending(gcuh => gcuh.CreatedOnUtc) - .Select(x => - { - return new GiftCardModel.GiftCardUsageHistoryModel() - { - Id = x.Id, - OrderId = x.UsedWithOrderId, - UsedValue = _priceFormatter.FormatPrice(x.UsedValue, true, false), - CreatedOn = _dateTimeHelper.ConvertToUserTime(x.CreatedOnUtc, DateTimeKind.Utc) - }; - }) - .ToList(); - var model = new GridModel - { - Data = usageHistoryModel.PagedForCommand(command), - Total = usageHistoryModel.Count - }; + var model = new GridModel(); + + if (_services.Permissions.Authorize(StandardPermissionProvider.ManageGiftCards)) + { + var giftCard = _giftCardService.GetGiftCardById(giftCardId); + + var usageHistoryModel = giftCard.GiftCardUsageHistory + .OrderByDescending(gcuh => gcuh.CreatedOnUtc) + .Select(x => + { + return new GiftCardModel.GiftCardUsageHistoryModel() + { + Id = x.Id, + OrderId = x.UsedWithOrderId, + UsedValue = _priceFormatter.FormatPrice(x.UsedValue, true, false), + CreatedOn = _dateTimeHelper.ConvertToUserTime(x.CreatedOnUtc, DateTimeKind.Utc) + }; + }) + .ToList(); + + model.Data = usageHistoryModel.PagedForCommand(command); + model.Total = usageHistoryModel.Count; + } + else + { + model.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } return new JsonResult { From 619e8dcb4426c7503ce455b9d6be10b0e7bf08b8 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Wed, 6 Jan 2016 12:19:09 +0100 Subject: [PATCH 134/626] Faulty permission handling in ajax grid actions (no message, infinite loading icon)(part 2) --- .../Controllers/WebApiController.cs | 2 +- .../Controllers/LanguageController.cs | 192 +- .../Controllers/LogController.cs | 78 +- .../Controllers/ManufacturerController.cs | 160 +- .../Controllers/MeasureController.cs | 198 +- .../Controllers/MessageTemplateController.cs | 20 +- .../Controllers/NewsController.cs | 138 +- .../NewsLetterSubscriptionController.cs | 70 +- .../Controllers/OnlineCustomerController.cs | 48 +- .../Controllers/OrderController.cs | 331 +-- .../Controllers/PollController.cs | 172 +- .../Controllers/ProductAttributeController.cs | 26 +- .../Controllers/ProductController.cs | 1766 +++++++++-------- .../Controllers/ProductReviewController.cs | 45 +- .../Controllers/QueuedEmailController.cs | 64 +- .../Controllers/RecurringPaymentController.cs | 81 +- .../Controllers/ReturnRequestController.cs | 38 +- .../Controllers/SettingController.cs | 173 +- .../Controllers/ShippingController.cs | 27 +- .../Controllers/ShoppingCartController.cs | 200 +- .../SpecificationAttributeController.cs | 96 +- .../Controllers/StoreController.cs | 35 +- .../Controllers/TaxController.cs | 83 +- .../Controllers/TopicController.cs | 27 +- .../Controllers/UrlRecordController.cs | 32 +- 25 files changed, 2200 insertions(+), 1902 deletions(-) diff --git a/src/Plugins/SmartStore.WebApi/Controllers/WebApiController.cs b/src/Plugins/SmartStore.WebApi/Controllers/WebApiController.cs index 808387b270..4fb254bbff 100644 --- a/src/Plugins/SmartStore.WebApi/Controllers/WebApiController.cs +++ b/src/Plugins/SmartStore.WebApi/Controllers/WebApiController.cs @@ -97,7 +97,7 @@ public ActionResult SaveGeneralSettings(WebApiConfigModel model) public ActionResult GridUserData(GridCommand command) { if (!HasPermission()) - return new JsonResult { Data = new GridModel { Data = new List() }}; + return new JsonResult { Data = new GridModel { Data = new List() } }; var model = _webApiPluginService.GetGridModel(command.Page - 1, command.PageSize); diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/LanguageController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/LanguageController.cs index e546998d03..02587df34f 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/LanguageController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/LanguageController.cs @@ -60,7 +60,8 @@ public LanguageController(ILanguageService languageService, } #endregion - #region Utilities + + #region Utilities [NonAction] private void PrepareFlagsModel(LanguageModel model) @@ -123,18 +124,25 @@ public ActionResult List() [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult List(GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageLanguages)) - return AccessDeniedView(); + var model = new GridModel(); + + if (_permissionService.Authorize(StandardPermissionProvider.ManageLanguages)) + { + var languages = _languageService.GetAllLanguages(true); + + model.Data = languages.Select(x => x.ToModel()); + model.Total = languages.Count(); + } + else + { + model.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } - var languages = _languageService.GetAllLanguages(true); - var gridModel = new GridModel - { - Data = languages.Select(x => x.ToModel()), - Total = languages.Count() - }; return new JsonResult { - Data = gridModel + Data = model }; } @@ -329,31 +337,37 @@ public ActionResult Resources(int languageId) [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult Resources(int languageId, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageLanguages)) - return AccessDeniedView(); + var model = new GridModel(); - var language = _languageService.GetLanguageById(languageId); + if (_permissionService.Authorize(StandardPermissionProvider.ManageLanguages)) + { + var language = _languageService.GetLanguageById(languageId); + + var resources = _localizationService + .GetResourceValues(languageId, true) + .OrderBy(x => x.Key) + .Where(x => x.Key != "!!___EOF___!!" && x.Value != null) + .Select(x => new LanguageResourceModel + { + LanguageId = languageId, + LanguageName = language.Name, + Id = x.Value.Item1, + Name = x.Key, + Value = x.Value.Item2.EmptyNull(), + }) + .ForCommand(command) + .ToList(); + + model.Data = resources.PagedForCommand(command); + model.Total = resources.Count; + } + else + { + model.Data = Enumerable.Empty(); - var resources = _localizationService - .GetResourceValues(languageId, true) - .OrderBy(x => x.Key) - .Where(x => x.Key != "!!___EOF___!!" && x.Value != null) - .Select(x => new LanguageResourceModel - { - LanguageId = languageId, - LanguageName = language.Name, - Id = x.Value.Item1, - Name = x.Key, - Value = x.Value.Item2.EmptyNull(), - }) - .ForCommand(command) - .ToList(); + NotifyAccessDenied(); + } - var model = new GridModel - { - Data = resources.PagedForCommand(command), - Total = resources.Count - }; return new JsonResult { Data = model @@ -363,36 +377,36 @@ public ActionResult Resources(int languageId, GridCommand command) [GridAction(EnableCustomBinding = true)] public ActionResult ResourceUpdate(LanguageResourceModel model, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageLanguages)) - return AccessDeniedView(); + if (_permissionService.Authorize(StandardPermissionProvider.ManageLanguages)) + { + if (model.Name != null) + model.Name = model.Name.Trim(); + if (model.Value != null) + model.Value = model.Value.Trim(); - if (model.Name != null) - model.Name = model.Name.Trim(); - if (model.Value != null) - model.Value = model.Value.Trim(); + if (!ModelState.IsValid) + { + var modelStateErrors = this.ModelState.Values.SelectMany(x => x.Errors).Select(x => x.ErrorMessage); + return Content(modelStateErrors.FirstOrDefault()); + } - if (!ModelState.IsValid) - { - //display the first model error - var modelStateErrors = this.ModelState.Values.SelectMany(x => x.Errors).Select(x => x.ErrorMessage); - return Content(modelStateErrors.FirstOrDefault()); - } + var resource = _localizationService.GetLocaleStringResourceById(model.Id); + // if the resourceName changed, ensure it isn't being used by another resource + if (!resource.ResourceName.Equals(model.Name, StringComparison.InvariantCultureIgnoreCase)) + { + var res = _localizationService.GetLocaleStringResourceByName(model.Name, model.LanguageId, false); + if (res != null && res.Id != resource.Id) + { + return Content(T("Admin.Configuration.Languages.Resources.NameAlreadyExists", res.ResourceName)); + } + } - var resource = _localizationService.GetLocaleStringResourceById(model.Id); - // if the resourceName changed, ensure it isn't being used by another resource - if (!resource.ResourceName.Equals(model.Name, StringComparison.InvariantCultureIgnoreCase)) - { - var res = _localizationService.GetLocaleStringResourceByName(model.Name, model.LanguageId, false); - if (res != null && res.Id != resource.Id) - { - return Content(string.Format(_localizationService.GetResource("Admin.Configuration.Languages.Resources.NameAlreadyExists"), res.ResourceName)); - } - } + resource.ResourceName = model.Name; + resource.ResourceValue = model.Value; + resource.IsTouched = true; - resource.ResourceName = model.Name; - resource.ResourceValue = model.Value; - resource.IsTouched = true; - _localizationService.UpdateLocaleStringResource(resource); + _localizationService.UpdateLocaleStringResource(resource); + } return Resources(model.LanguageId, command); } @@ -400,47 +414,47 @@ public ActionResult ResourceUpdate(LanguageResourceModel model, GridCommand comm [GridAction(EnableCustomBinding = true)] public ActionResult ResourceAdd(int id, LanguageResourceModel model, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageLanguages)) - return AccessDeniedView(); + if (_permissionService.Authorize(StandardPermissionProvider.ManageLanguages)) + { + if (model.Name != null) + model.Name = model.Name.Trim(); + if (model.Value != null) + model.Value = model.Value.Trim(); - if (model.Name != null) - model.Name = model.Name.Trim(); - if (model.Value != null) - model.Value = model.Value.Trim(); + if (!ModelState.IsValid) + { + var modelStateErrors = this.ModelState.Values.SelectMany(x => x.Errors).Select(x => x.ErrorMessage); + return Content(modelStateErrors.FirstOrDefault()); + } - if (!ModelState.IsValid) - { - //display the first model error - var modelStateErrors = this.ModelState.Values.SelectMany(x => x.Errors).Select(x => x.ErrorMessage); - return Content(modelStateErrors.FirstOrDefault()); - } + var res = _localizationService.GetLocaleStringResourceByName(model.Name, model.LanguageId, false); + if (res == null) + { + var resource = new LocaleStringResource { LanguageId = id }; + resource.ResourceName = model.Name; + resource.ResourceValue = model.Value; + resource.IsTouched = true; + + _localizationService.InsertLocaleStringResource(resource); + } + else + { + return Content(T("Admin.Configuration.Languages.Resources.NameAlreadyExists", model.Name)); + } + } - var res = _localizationService.GetLocaleStringResourceByName(model.Name, model.LanguageId, false); - if (res == null) - { - var resource = new LocaleStringResource { LanguageId = id }; - resource.ResourceName = model.Name; - resource.ResourceValue = model.Value; - resource.IsTouched = true; - _localizationService.InsertLocaleStringResource(resource); - } - else - { - return Content(string.Format(_localizationService.GetResource("Admin.Configuration.Languages.Resources.NameAlreadyExists"), model.Name)); - } return Resources(id, command); } [GridAction(EnableCustomBinding = true)] public ActionResult ResourceDelete(int id, int languageId, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageLanguages)) - return AccessDeniedView(); + if (_permissionService.Authorize(StandardPermissionProvider.ManageLanguages)) + { + var resource = _localizationService.GetLocaleStringResourceById(id); - var resource = _localizationService.GetLocaleStringResourceById(id); - if (resource == null) - throw new ArgumentException("No resource found with the specified id"); - _localizationService.DeleteLocaleStringResource(resource); + _localizationService.DeleteLocaleStringResource(resource); + } return Resources(languageId, command); } diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/LogController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/LogController.cs index 8b82d5d894..9fb8db0105 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/LogController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/LogController.cs @@ -64,49 +64,55 @@ public ActionResult List() [GridAction(EnableCustomBinding = true)] public ActionResult LogList(GridCommand command, LogListModel model) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageSystemLog)) - return AccessDeniedView(); - - DateTime? createdOnFromValue = (model.CreatedOnFrom == null) ? null - : (DateTime?)_dateTimeHelper.ConvertToUtcTime(model.CreatedOnFrom.Value, _dateTimeHelper.CurrentTimeZone); - - DateTime? createdToFromValue = (model.CreatedOnTo == null) ? null - : (DateTime?)_dateTimeHelper.ConvertToUtcTime(model.CreatedOnTo.Value, _dateTimeHelper.CurrentTimeZone).AddDays(1); - - LogLevel? logLevel = model.LogLevelId > 0 ? (LogLevel?)(model.LogLevelId) : null; - - - var logItems = Logger.GetAllLogs(createdOnFromValue, createdToFromValue, model.Message, - logLevel, command.Page - 1, command.PageSize, model.MinFrequency); - - var gridModel = new GridModel - { - Data = logItems.Select(x => - { - var logModel = new LogModel() - { - Id = x.Id, - LogLevelHint = s_logLevelHintMap[x.LogLevel], - LogLevel = x.LogLevel.GetLocalizedEnum(_localizationService, _workContext), - ShortMessage = x.ShortMessage, - FullMessage = x.FullMessage, - IpAddress = x.IpAddress, - CustomerId = x.CustomerId, - CustomerEmail = x.Customer != null ? x.Customer.Email : null, - PageUrl = x.PageUrl, - ReferrerUrl = x.ReferrerUrl, - CreatedOn = _dateTimeHelper.ConvertToUserTime(x.CreatedOnUtc, DateTimeKind.Utc), + var gridModel = new GridModel(); + + if (_permissionService.Authorize(StandardPermissionProvider.ManageSystemLog)) + { + DateTime? createdOnFromValue = (model.CreatedOnFrom == null) ? null + : (DateTime?)_dateTimeHelper.ConvertToUtcTime(model.CreatedOnFrom.Value, _dateTimeHelper.CurrentTimeZone); + + DateTime? createdToFromValue = (model.CreatedOnTo == null) ? null + : (DateTime?)_dateTimeHelper.ConvertToUtcTime(model.CreatedOnTo.Value, _dateTimeHelper.CurrentTimeZone).AddDays(1); + + LogLevel? logLevel = model.LogLevelId > 0 ? (LogLevel?)(model.LogLevelId) : null; + + var logItems = Logger.GetAllLogs(createdOnFromValue, createdToFromValue, model.Message, + logLevel, command.Page - 1, command.PageSize, model.MinFrequency); + + gridModel.Data = logItems.Select(x => + { + var logModel = new LogModel + { + Id = x.Id, + LogLevelHint = s_logLevelHintMap[x.LogLevel], + LogLevel = x.LogLevel.GetLocalizedEnum(_localizationService, _workContext), + ShortMessage = x.ShortMessage, + FullMessage = x.FullMessage, + IpAddress = x.IpAddress, + CustomerId = x.CustomerId, + CustomerEmail = x.Customer != null ? x.Customer.Email : null, + PageUrl = x.PageUrl, + ReferrerUrl = x.ReferrerUrl, + CreatedOn = _dateTimeHelper.ConvertToUserTime(x.CreatedOnUtc, DateTimeKind.Utc), Frequency = x.Frequency, ContentHash = x.ContentHash - }; + }; if (x.UpdatedOnUtc.HasValue) logModel.UpdatedOn = _dateTimeHelper.ConvertToUserTime(x.UpdatedOnUtc.Value, DateTimeKind.Utc); return logModel; - }), - Total = logItems.TotalCount - }; + }); + + gridModel.Total = logItems.TotalCount; + } + else + { + gridModel.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } + return new JsonResult { Data = gridModel diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/ManufacturerController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/ManufacturerController.cs index e107a81fac..5f345fcb42 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/ManufacturerController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/ManufacturerController.cs @@ -254,16 +254,21 @@ public ActionResult List() [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult List(GridCommand command, ManufacturerListModel model) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); + var gridModel = new GridModel(); - var manufacturers = _manufacturerService.GetAllManufacturers(model.SearchManufacturerName, command.Page - 1, command.PageSize, true); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + var manufacturers = _manufacturerService.GetAllManufacturers(model.SearchManufacturerName, command.Page - 1, command.PageSize, true); - var gridModel = new GridModel - { - Data = manufacturers.Select(x => x.ToModel()), - Total = manufacturers.TotalCount - }; + gridModel.Data = manufacturers.Select(x => x.ToModel()); + gridModel.Total = manufacturers.TotalCount; + } + else + { + gridModel.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } return new JsonResult { @@ -441,35 +446,43 @@ public ActionResult Delete(int id) [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult ProductList(GridCommand command, int manufacturerId) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); + var model = new GridModel(); + + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + var productManufacturers = _manufacturerService.GetProductManufacturersByManufacturerId(manufacturerId, command.Page - 1, command.PageSize, true); - var productManufacturers = _manufacturerService.GetProductManufacturersByManufacturerId(manufacturerId, - command.Page - 1, command.PageSize, true); + var productIds = productManufacturers.Select(x => x.ProductId).ToArray(); + var products = _productService.GetProductsByIds(productIds); - var model = new GridModel - { - Data = productManufacturers - .Select(x => - { - var product = _productService.GetProductById(x.ProductId); + model.Data = productManufacturers + .Select(x => + { + var product = products.FirstOrDefault(y => y.Id == x.ProductId); + + return new ManufacturerModel.ManufacturerProductModel + { + Id = x.Id, + ManufacturerId = x.ManufacturerId, + ProductId = x.ProductId, + ProductName = product.Name, + Sku = product.Sku, + ProductTypeName = product.GetProductTypeLabel(_localizationService), + ProductTypeLabelHint = product.ProductTypeLabelHint, + Published = product.Published, + IsFeaturedProduct = x.IsFeaturedProduct, + DisplayOrder1 = x.DisplayOrder + }; + }); - return new ManufacturerModel.ManufacturerProductModel() - { - Id = x.Id, - ManufacturerId = x.ManufacturerId, - ProductId = x.ProductId, - ProductName = product.Name, - Sku = product.Sku, - ProductTypeName = product.GetProductTypeLabel(_localizationService), - ProductTypeLabelHint = product.ProductTypeLabelHint, - Published = product.Published, - IsFeaturedProduct = x.IsFeaturedProduct, - DisplayOrder1 = x.DisplayOrder - }; - }), - Total = productManufacturers.TotalCount - }; + model.Total = productManufacturers.TotalCount; + } + else + { + model.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } return new JsonResult { @@ -480,16 +493,15 @@ public ActionResult ProductList(GridCommand command, int manufacturerId) [GridAction(EnableCustomBinding = true)] public ActionResult ProductUpdate(GridCommand command, ManufacturerModel.ManufacturerProductModel model) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); + var productManufacturer = _manufacturerService.GetProductManufacturerById(model.Id); - var productManufacturer = _manufacturerService.GetProductManufacturerById(model.Id); - if (productManufacturer == null) - throw new ArgumentException("No product manufacturer mapping found with the specified id"); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + productManufacturer.IsFeaturedProduct = model.IsFeaturedProduct; + productManufacturer.DisplayOrder = model.DisplayOrder1; - productManufacturer.IsFeaturedProduct = model.IsFeaturedProduct; - productManufacturer.DisplayOrder = model.DisplayOrder1; - _manufacturerService.UpdateProductManufacturer(productManufacturer); + _manufacturerService.UpdateProductManufacturer(productManufacturer); + } return ProductList(command, productManufacturer.ManufacturerId); } @@ -497,15 +509,13 @@ public ActionResult ProductUpdate(GridCommand command, ManufacturerModel.Manufac [GridAction(EnableCustomBinding = true)] public ActionResult ProductDelete(int id, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); - - var productManufacturer = _manufacturerService.GetProductManufacturerById(id); - if (productManufacturer == null) - throw new ArgumentException("No product manufacturer mapping found with the specified id"); + var productManufacturer = _manufacturerService.GetProductManufacturerById(id); + var manufacturerId = productManufacturer.ManufacturerId; - var manufacturerId = productManufacturer.ManufacturerId; - _manufacturerService.DeleteProductManufacturer(productManufacturer); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + _manufacturerService.DeleteProductManufacturer(productManufacturer); + } return ProductList(command, manufacturerId); } @@ -560,35 +570,43 @@ public ActionResult ProductAddPopup(int manufacturerId) [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult ProductAddPopupList(GridCommand command, ManufacturerModel.AddManufacturerProductModel model) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); + var gridModel = new GridModel(); - var gridModel = new GridModel(); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + var ctx = new ProductSearchContext(); - var ctx = new ProductSearchContext(); + if (model.SearchCategoryId > 0) + ctx.CategoryIds.Add(model.SearchCategoryId); - if (model.SearchCategoryId > 0) - ctx.CategoryIds.Add(model.SearchCategoryId); + ctx.ManufacturerId = model.SearchManufacturerId; + ctx.Keywords = model.SearchProductName; + ctx.LanguageId = _workContext.WorkingLanguage.Id; + ctx.OrderBy = ProductSortingEnum.Position; + ctx.PageIndex = command.Page - 1; + ctx.PageSize = command.PageSize; + ctx.ShowHidden = true; + ctx.ProductType = model.SearchProductTypeId > 0 ? (ProductType?)model.SearchProductTypeId : null; - ctx.ManufacturerId = model.SearchManufacturerId; - ctx.Keywords = model.SearchProductName; - ctx.LanguageId = _workContext.WorkingLanguage.Id; - ctx.OrderBy = ProductSortingEnum.Position; - ctx.PageIndex = command.Page - 1; - ctx.PageSize = command.PageSize; - ctx.ShowHidden = true; - ctx.ProductType = model.SearchProductTypeId > 0 ? (ProductType?)model.SearchProductTypeId : null; + var products = _productService.SearchProducts(ctx); - var products = _productService.SearchProducts(ctx); + gridModel.Data = products.Select(x => + { + var productModel = x.ToModel(); + productModel.ProductTypeName = x.GetProductTypeLabel(_localizationService); + + return productModel; + }); - gridModel.Data = products.Select(x => + gridModel.Total = products.TotalCount; + } + else { - var productModel = x.ToModel(); - productModel.ProductTypeName = x.GetProductTypeLabel(_localizationService); + gridModel.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } - return productModel; - }); - gridModel.Total = products.TotalCount; return new JsonResult { Data = gridModel diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/MeasureController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/MeasureController.cs index ec1265db77..f8b33e6102 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/MeasureController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/MeasureController.cs @@ -79,20 +79,29 @@ public ActionResult Weights(string id) [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult Weights(GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageMeasures)) - return AccessDeniedView(); + var model = new GridModel(); - var weightsModel = _measureService.GetAllMeasureWeights() - .Select(x => x.ToModel()) - .ForCommand(command) - .ToList(); - foreach (var wm in weightsModel) - wm.IsPrimaryWeight = wm.Id == _measureSettings.BaseWeightId; - var model = new GridModel - { - Data = weightsModel, - Total = weightsModel.Count - }; + if (_permissionService.Authorize(StandardPermissionProvider.ManageMeasures)) + { + var weightsModel = _measureService.GetAllMeasureWeights() + .Select(x => x.ToModel()) + .ForCommand(command) + .ToList(); + + foreach (var wm in weightsModel) + { + wm.IsPrimaryWeight = wm.Id == _measureSettings.BaseWeightId; + } + + model.Data = weightsModel; + model.Total = weightsModel.Count; + } + else + { + model.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } return new JsonResult { @@ -100,22 +109,22 @@ public ActionResult Weights(GridCommand command) }; } - [GridAction(EnableCustomBinding=true)] + [GridAction(EnableCustomBinding = true)] public ActionResult WeightUpdate(MeasureWeightModel model, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageMeasures)) - return AccessDeniedView(); - - if (!ModelState.IsValid) - { - //display the first model error - var modelStateErrors = this.ModelState.Values.SelectMany(x => x.Errors).Select(x => x.ErrorMessage); - return Content(modelStateErrors.FirstOrDefault()); - } + if (_permissionService.Authorize(StandardPermissionProvider.ManageMeasures)) + { + if (!ModelState.IsValid) + { + var modelStateErrors = this.ModelState.Values.SelectMany(x => x.Errors).Select(x => x.ErrorMessage); + return Content(modelStateErrors.FirstOrDefault()); + } - var weight = _measureService.GetMeasureWeightById(model.Id); - weight = model.ToEntity(weight); - _measureService.UpdateMeasureWeight(weight); + var weight = _measureService.GetMeasureWeightById(model.Id); + weight = model.ToEntity(weight); + + _measureService.UpdateMeasureWeight(weight); + } return Weights(command); } @@ -123,19 +132,19 @@ public ActionResult WeightUpdate(MeasureWeightModel model, GridCommand command) [GridAction(EnableCustomBinding = true)] public ActionResult WeightAdd([Bind(Exclude="Id")] MeasureWeightModel model, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageMeasures)) - return AccessDeniedView(); + if (_permissionService.Authorize(StandardPermissionProvider.ManageMeasures)) + { + if (!ModelState.IsValid) + { + var modelStateErrors = this.ModelState.Values.SelectMany(x => x.Errors).Select(x => x.ErrorMessage); + return Content(modelStateErrors.FirstOrDefault()); + } - if (!ModelState.IsValid) - { - //display the first model error - var modelStateErrors = this.ModelState.Values.SelectMany(x => x.Errors).Select(x => x.ErrorMessage); - return Content(modelStateErrors.FirstOrDefault()); - } + var weight = new MeasureWeight(); + weight = model.ToEntity(weight); - var weight = new MeasureWeight(); - weight = model.ToEntity(weight); - _measureService.InsertMeasureWeight(weight); + _measureService.InsertMeasureWeight(weight); + } return Weights(command); } @@ -143,17 +152,17 @@ public ActionResult WeightAdd([Bind(Exclude="Id")] MeasureWeightModel model, Gri [GridAction(EnableCustomBinding = true)] public ActionResult WeightDelete(int id, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageMeasures)) - return AccessDeniedView(); - - var weight = _measureService.GetMeasureWeightById(id); - if (weight == null) - throw new ArgumentException("No weight found with the specified id"); + if (_permissionService.Authorize(StandardPermissionProvider.ManageMeasures)) + { + var weight = _measureService.GetMeasureWeightById(id); - if (weight.Id == _measureSettings.BaseWeightId) - return Content(_localizationService.GetResource("Admin.Configuration.Measures.Weights.CantDeletePrimary")); + if (weight.Id == _measureSettings.BaseWeightId) + { + return Content(T("Admin.Configuration.Measures.Weights.CantDeletePrimary")); + } - _measureService.DeleteMeasureWeight(weight); + _measureService.DeleteMeasureWeight(weight); + } return Weights(command); } @@ -195,20 +204,29 @@ public ActionResult Dimensions(string id) [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult Dimensions(GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageMeasures)) - return AccessDeniedView(); + var model = new GridModel(); - var dimensionsModel = _measureService.GetAllMeasureDimensions() - .Select(x => x.ToModel()) - .ForCommand(command) - .ToList(); - foreach (var wm in dimensionsModel) - wm.IsPrimaryDimension = wm.Id == _measureSettings.BaseDimensionId; - var model = new GridModel - { - Data = dimensionsModel, - Total = dimensionsModel.Count - }; + if (_permissionService.Authorize(StandardPermissionProvider.ManageMeasures)) + { + var dimensionsModel = _measureService.GetAllMeasureDimensions() + .Select(x => x.ToModel()) + .ForCommand(command) + .ToList(); + + foreach (var wm in dimensionsModel) + { + wm.IsPrimaryDimension = wm.Id == _measureSettings.BaseDimensionId; + } + + model.Data = dimensionsModel; + model.Total = dimensionsModel.Count; + } + else + { + model.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } return new JsonResult { @@ -219,19 +237,19 @@ public ActionResult Dimensions(GridCommand command) [GridAction(EnableCustomBinding = true)] public ActionResult DimensionUpdate(MeasureDimensionModel model, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageMeasures)) - return AccessDeniedView(); + if (_permissionService.Authorize(StandardPermissionProvider.ManageMeasures)) + { + if (!ModelState.IsValid) + { + var modelStateErrors = this.ModelState.Values.SelectMany(x => x.Errors).Select(x => x.ErrorMessage); + return Content(modelStateErrors.FirstOrDefault()); + } - if (!ModelState.IsValid) - { - //display the first model error - var modelStateErrors = this.ModelState.Values.SelectMany(x => x.Errors).Select(x => x.ErrorMessage); - return Content(modelStateErrors.FirstOrDefault()); - } + var dimension = _measureService.GetMeasureDimensionById(model.Id); + dimension = model.ToEntity(dimension); - var dimension = _measureService.GetMeasureDimensionById(model.Id); - dimension = model.ToEntity(dimension); - _measureService.UpdateMeasureDimension(dimension); + _measureService.UpdateMeasureDimension(dimension); + } return Dimensions(command); } @@ -239,19 +257,19 @@ public ActionResult DimensionUpdate(MeasureDimensionModel model, GridCommand com [GridAction(EnableCustomBinding = true)] public ActionResult DimensionAdd([Bind(Exclude="Id")] MeasureDimensionModel model, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageMeasures)) - return AccessDeniedView(); + if (_permissionService.Authorize(StandardPermissionProvider.ManageMeasures)) + { + if (!ModelState.IsValid) + { + var modelStateErrors = this.ModelState.Values.SelectMany(x => x.Errors).Select(x => x.ErrorMessage); + return Content(modelStateErrors.FirstOrDefault()); + } - if (!ModelState.IsValid) - { - //display the first model error - var modelStateErrors = this.ModelState.Values.SelectMany(x => x.Errors).Select(x => x.ErrorMessage); - return Content(modelStateErrors.FirstOrDefault()); - } + var dimension = new MeasureDimension(); + dimension = model.ToEntity(dimension); - var dimension = new MeasureDimension(); - dimension = model.ToEntity(dimension); - _measureService.InsertMeasureDimension(dimension); + _measureService.InsertMeasureDimension(dimension); + } return Dimensions(command); } @@ -259,17 +277,17 @@ public ActionResult DimensionAdd([Bind(Exclude="Id")] MeasureDimensionModel mode [GridAction(EnableCustomBinding = true)] public ActionResult DimensionDelete(int id, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageMeasures)) - return AccessDeniedView(); - - var dimension = _measureService.GetMeasureDimensionById(id); - if (dimension == null) - throw new ArgumentException("No dimension found with the specified id"); + if (_permissionService.Authorize(StandardPermissionProvider.ManageMeasures)) + { + var dimension = _measureService.GetMeasureDimensionById(id); - if (dimension.Id == _measureSettings.BaseDimensionId) - return Content(_localizationService.GetResource("Admin.Configuration.Measures.Dimensions.CantDeletePrimary")); + if (dimension.Id == _measureSettings.BaseDimensionId) + { + return Content(T("Admin.Configuration.Measures.Dimensions.CantDeletePrimary")); + } - _measureService.DeleteMeasureDimension(dimension); + _measureService.DeleteMeasureDimension(dimension); + } return Dimensions(command); } diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/MessageTemplateController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/MessageTemplateController.cs index be6c73a92b..eb0b111b06 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/MessageTemplateController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/MessageTemplateController.cs @@ -162,15 +162,21 @@ public ActionResult List() [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult List(GridCommand command, MessageTemplateListModel model) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageMessageTemplates)) - return AccessDeniedView(); + var gridModel = new GridModel(); - var messageTemplates = _messageTemplateService.GetAllMessageTemplates(model.SearchStoreId); - var gridModel = new GridModel + if (_permissionService.Authorize(StandardPermissionProvider.ManageMessageTemplates)) { - Data = messageTemplates.Select(x => x.ToModel()), - Total = messageTemplates.Count - }; + var messageTemplates = _messageTemplateService.GetAllMessageTemplates(model.SearchStoreId); + + gridModel.Data = messageTemplates.Select(x => x.ToModel()); + gridModel.Total = messageTemplates.Count; + } + else + { + gridModel.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } return new JsonResult { diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/NewsController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/NewsController.cs index 2ac51b9184..2d12ecc9d6 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/NewsController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/NewsController.cs @@ -115,26 +115,38 @@ public ActionResult List() [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult List(GridCommand command, NewsItemListModel model) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageNews)) - return AccessDeniedView(); + var gridModel = new GridModel(); + + if (_permissionService.Authorize(StandardPermissionProvider.ManageNews)) + { + var news = _newsService.GetAllNews(0, model.SearchStoreId, command.Page - 1, command.PageSize, true); + + gridModel.Data = news.Select(x => + { + var m = x.ToModel(); + + if (x.StartDateUtc.HasValue) + m.StartDate = _dateTimeHelper.ConvertToUserTime(x.StartDateUtc.Value, DateTimeKind.Utc); + + if (x.EndDateUtc.HasValue) + m.EndDate = _dateTimeHelper.ConvertToUserTime(x.EndDateUtc.Value, DateTimeKind.Utc); + + m.CreatedOn = _dateTimeHelper.ConvertToUserTime(x.CreatedOnUtc, DateTimeKind.Utc); + m.LanguageName = x.Language.Name; + m.Comments = x.ApprovedCommentCount + x.NotApprovedCommentCount; + + return m; + }); + + gridModel.Total = news.TotalCount; + } + else + { + gridModel.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } - var news = _newsService.GetAllNews(0, model.SearchStoreId, command.Page - 1, command.PageSize, true); - var gridModel = new GridModel - { - Data = news.Select(x => - { - var m = x.ToModel(); - if (x.StartDateUtc.HasValue) - m.StartDate = _dateTimeHelper.ConvertToUserTime(x.StartDateUtc.Value, DateTimeKind.Utc); - if (x.EndDateUtc.HasValue) - m.EndDate = _dateTimeHelper.ConvertToUserTime(x.EndDateUtc.Value, DateTimeKind.Utc); - m.CreatedOn = _dateTimeHelper.ConvertToUserTime(x.CreatedOnUtc, DateTimeKind.Utc); - m.LanguageName = x.Language.Name; - m.Comments = x.ApprovedCommentCount + x.NotApprovedCommentCount; - return m; - }), - Total = news.TotalCount - }; return new JsonResult { Data = gridModel @@ -297,47 +309,54 @@ public ActionResult Comments(int? filterByNewsItemId) [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult Comments(int? filterByNewsItemId, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageNews)) - return AccessDeniedView(); + var gridModel = new GridModel(); - IList comments; - if (filterByNewsItemId.HasValue) - { - //filter comments by news item - var newsItem = _newsService.GetNewsById(filterByNewsItemId.Value); - comments = newsItem.NewsComments.OrderBy(bc => bc.CreatedOnUtc).ToList(); - } - else - { - //load all news comments - comments = _customerContentService.GetAllCustomerContent(0, null); - } + if (_permissionService.Authorize(StandardPermissionProvider.ManageNews)) + { + IList comments; + if (filterByNewsItemId.HasValue) + { + //filter comments by news item + var newsItem = _newsService.GetNewsById(filterByNewsItemId.Value); + comments = newsItem.NewsComments.OrderBy(bc => bc.CreatedOnUtc).ToList(); + } + else + { + //load all news comments + comments = _customerContentService.GetAllCustomerContent(0, null); + } - var gridModel = new GridModel - { - Data = comments.PagedForCommand(command).Select(newsComment => - { - var commentModel = new NewsCommentModel(); + gridModel.Data = comments.PagedForCommand(command).Select(newsComment => + { + var commentModel = new NewsCommentModel(); var customer = _customerService.GetCustomerById(newsComment.CustomerId); - commentModel.Id = newsComment.Id; - commentModel.NewsItemId = newsComment.NewsItemId; - commentModel.NewsItemTitle = newsComment.NewsItem.Title; - commentModel.CustomerId = newsComment.CustomerId; - commentModel.IpAddress = newsComment.IpAddress; - commentModel.CreatedOn = _dateTimeHelper.ConvertToUserTime(newsComment.CreatedOnUtc, DateTimeKind.Utc); - commentModel.CommentTitle = newsComment.CommentTitle; - commentModel.CommentText = Core.Html.HtmlUtils.FormatText(newsComment.CommentText, false, true, false, false, false, false); + commentModel.Id = newsComment.Id; + commentModel.NewsItemId = newsComment.NewsItemId; + commentModel.NewsItemTitle = newsComment.NewsItem.Title; + commentModel.CustomerId = newsComment.CustomerId; + commentModel.IpAddress = newsComment.IpAddress; + commentModel.CreatedOn = _dateTimeHelper.ConvertToUserTime(newsComment.CreatedOnUtc, DateTimeKind.Utc); + commentModel.CommentTitle = newsComment.CommentTitle; + commentModel.CommentText = Core.Html.HtmlUtils.FormatText(newsComment.CommentText, false, true, false, false, false, false); if (customer == null) commentModel.CustomerName = "".NaIfEmpty(); else commentModel.CustomerName = customer.GetFullName(); - return commentModel; - }), - Total = comments.Count, - }; + return commentModel; + }); + + gridModel.Total = comments.Count; + } + else + { + gridModel.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } + return new JsonResult { Data = gridModel @@ -347,17 +366,16 @@ public ActionResult Comments(int? filterByNewsItemId, GridCommand command) [GridAction(EnableCustomBinding = true)] public ActionResult CommentDelete(int? filterByNewsItemId, int id, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageNews)) - return AccessDeniedView(); - - var comment = _customerContentService.GetCustomerContentById(id) as NewsComment; - if (comment == null) - throw new ArgumentException("No comment found with the specified id"); + if (_permissionService.Authorize(StandardPermissionProvider.ManageNews)) + { + var comment = _customerContentService.GetCustomerContentById(id) as NewsComment; - var newsItem = comment.NewsItem; - _customerContentService.DeleteCustomerContent(comment); - //update totals - _newsService.UpdateCommentTotals(newsItem); + var newsItem = comment.NewsItem; + _customerContentService.DeleteCustomerContent(comment); + + //update totals + _newsService.UpdateCommentTotals(newsItem); + } return Comments(filterByNewsItemId, command); } diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/NewsLetterSubscriptionController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/NewsLetterSubscriptionController.cs index e8e92184a2..9c688979ea 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/NewsLetterSubscriptionController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/NewsLetterSubscriptionController.cs @@ -68,7 +68,7 @@ public ActionResult List() var store = _storeService.GetStoreById(x.StoreId); m.CreatedOn = _dateTimeHelper.ConvertToUserTime(x.CreatedOnUtc, DateTimeKind.Utc); - m.StoreName = store != null ? store.Name : "Unknown"; + m.StoreName = store != null ? store.Name : "".NaIfEmpty(); return m; }), @@ -80,26 +80,33 @@ public ActionResult List() [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult SubscriptionList(GridCommand command, NewsLetterSubscriptionListModel model) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageNewsletterSubscribers)) - return AccessDeniedView(); + var gridModel = new GridModel(); - var newsletterSubscriptions = _newsLetterSubscriptionService.GetAllNewsLetterSubscriptions( - model.SearchEmail, command.Page - 1, command.PageSize, true, model.StoreId); + if (_permissionService.Authorize(StandardPermissionProvider.ManageNewsletterSubscribers)) + { + var newsletterSubscriptions = _newsLetterSubscriptionService.GetAllNewsLetterSubscriptions( + model.SearchEmail, command.Page - 1, command.PageSize, true, model.StoreId); - var gridModel = new GridModel - { - Data = newsletterSubscriptions.Select(x => + gridModel.Data = newsletterSubscriptions.Select(x => { var m = x.ToModel(); var store = _storeService.GetStoreById(x.StoreId); m.CreatedOn = _dateTimeHelper.ConvertToUserTime(x.CreatedOnUtc, DateTimeKind.Utc); - m.StoreName = store != null ? store.Name : "Unknown"; + m.StoreName = store != null ? store.Name : "".NaIfEmpty(); return m; - }), - Total = newsletterSubscriptions.TotalCount - }; + }); + + gridModel.Total = newsletterSubscriptions.TotalCount; + } + else + { + gridModel.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } + return new JsonResult { Data = gridModel @@ -109,39 +116,36 @@ public ActionResult SubscriptionList(GridCommand command, NewsLetterSubscription [GridAction(EnableCustomBinding = true)] public ActionResult SubscriptionUpdate(NewsLetterSubscriptionModel model, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageNewsletterSubscribers)) - return AccessDeniedView(); - - if (!ModelState.IsValid) - { - //display the first model error - var modelStateErrors = this.ModelState.Values.SelectMany(x => x.Errors).Select(x => x.ErrorMessage); - return Content(modelStateErrors.FirstOrDefault()); - } + if (_permissionService.Authorize(StandardPermissionProvider.ManageNewsletterSubscribers)) + { + if (!ModelState.IsValid) + { + var modelStateErrors = this.ModelState.Values.SelectMany(x => x.Errors).Select(x => x.ErrorMessage); + return Content(modelStateErrors.FirstOrDefault()); + } - var subscription = _newsLetterSubscriptionService.GetNewsLetterSubscriptionById(model.Id); - subscription.Email = model.Email; - subscription.Active = model.Active; + var subscription = _newsLetterSubscriptionService.GetNewsLetterSubscriptionById(model.Id); + subscription.Email = model.Email; + subscription.Active = model.Active; - _newsLetterSubscriptionService.UpdateNewsLetterSubscription(subscription); + _newsLetterSubscriptionService.UpdateNewsLetterSubscription(subscription); + } var listModel = new NewsLetterSubscriptionListModel(); PrepareNewsLetterSubscriptionListModel(listModel); - return SubscriptionList(command, listModel); + return SubscriptionList(command, listModel); } [GridAction(EnableCustomBinding = true)] public ActionResult SubscriptionDelete(int id, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageNewsletterSubscribers)) - return AccessDeniedView(); - - var subscription = _newsLetterSubscriptionService.GetNewsLetterSubscriptionById(id); - if (subscription == null) - throw new ArgumentException("No subscription found with the specified id"); + if (_permissionService.Authorize(StandardPermissionProvider.ManageNewsletterSubscribers)) + { + var subscription = _newsLetterSubscriptionService.GetNewsLetterSubscriptionById(id); - _newsLetterSubscriptionService.DeleteNewsLetterSubscription(subscription); + _newsLetterSubscriptionService.DeleteNewsLetterSubscription(subscription); + } var listModel = new NewsLetterSubscriptionListModel(); PrepareNewsLetterSubscriptionListModel(listModel); diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/OnlineCustomerController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/OnlineCustomerController.cs index 222bb0863e..3aca0ddd54 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/OnlineCustomerController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/OnlineCustomerController.cs @@ -81,27 +81,35 @@ public ActionResult List() [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult List(GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCustomers)) - return AccessDeniedView(); + var model = new GridModel(); + + if (_permissionService.Authorize(StandardPermissionProvider.ManageCustomers)) + { + var lastActivityFrom = DateTime.UtcNow.AddMinutes(-_customerSettings.OnlineCustomerMinutes); + var customers = _customerService.GetOnlineCustomers(lastActivityFrom, null, command.Page - 1, command.PageSize); + + model.Data = customers.Select(x => + { + return new OnlineCustomerModel + { + Id = x.Id, + CustomerInfo = x.IsRegistered() ? x.Email : T("Admin.Customers.Guest").Text, + LastIpAddress = x.LastIpAddress, + Location = _geoCountryLookup.LookupCountryName(x.LastIpAddress), + LastActivityDate = _dateTimeHelper.ConvertToUserTime(x.LastActivityDateUtc, DateTimeKind.Utc), + LastVisitedPage = x.GetAttribute(SystemCustomerAttributeNames.LastVisitedPage) + }; + }); + + model.Total = customers.TotalCount; + } + else + { + model.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } - var customers = _customerService.GetOnlineCustomers(DateTime.UtcNow.AddMinutes(-_customerSettings.OnlineCustomerMinutes), - null, command.Page - 1, command.PageSize); - var model = new GridModel - { - Data = customers.Select(x => - { - return new OnlineCustomerModel() - { - Id = x.Id, - CustomerInfo = x.IsRegistered() ? x.Email : _localizationService.GetResource("Admin.Customers.Guest"), - LastIpAddress = x.LastIpAddress, - Location = _geoCountryLookup.LookupCountryName(x.LastIpAddress), - LastActivityDate = _dateTimeHelper.ConvertToUserTime(x.LastActivityDateUtc, DateTimeKind.Utc), - LastVisitedPage = x.GetAttribute(SystemCustomerAttributeNames.LastVisitedPage) - }; - }), - Total = customers.TotalCount - }; return new JsonResult { Data = model diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/OrderController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/OrderController.cs index f7adf8147d..911d14b44b 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/OrderController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/OrderController.cs @@ -809,57 +809,65 @@ public ActionResult List(OrderListModel model) [GridAction(EnableCustomBinding = true)] public ActionResult OrderList(GridCommand command, OrderListModel model) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageOrders)) - return AccessDeniedView(); + var gridModel = new GridModel(); - DateTime? startDateValue = (model.StartDate == null) ? null : (DateTime?)_dateTimeHelper.ConvertToUtcTime(model.StartDate.Value, _dateTimeHelper.CurrentTimeZone); - DateTime? endDateValue = (model.EndDate == null) ? null : (DateTime?)_dateTimeHelper.ConvertToUtcTime(model.EndDate.Value, _dateTimeHelper.CurrentTimeZone).AddDays(1); + if (_permissionService.Authorize(StandardPermissionProvider.ManageOrders)) + { + DateTime? startDateValue = (model.StartDate == null) ? null : (DateTime?)_dateTimeHelper.ConvertToUtcTime(model.StartDate.Value, _dateTimeHelper.CurrentTimeZone); + DateTime? endDateValue = (model.EndDate == null) ? null : (DateTime?)_dateTimeHelper.ConvertToUtcTime(model.EndDate.Value, _dateTimeHelper.CurrentTimeZone).AddDays(1); - var orderStatusIds = model.OrderStatusIds.ToIntArray(); - var paymentStatusIds = model.PaymentStatusIds.ToIntArray(); - var shippingStatusIds = model.ShippingStatusIds.ToIntArray(); + var orderStatusIds = model.OrderStatusIds.ToIntArray(); + var paymentStatusIds = model.PaymentStatusIds.ToIntArray(); + var shippingStatusIds = model.ShippingStatusIds.ToIntArray(); - var orders = _orderService.SearchOrders(model.StoreId, 0, startDateValue, endDateValue, orderStatusIds, paymentStatusIds, shippingStatusIds, - model.CustomerEmail, model.OrderGuid, model.OrderNumber, command.Page - 1, command.PageSize, model.CustomerName); + var orders = _orderService.SearchOrders(model.StoreId, 0, startDateValue, endDateValue, orderStatusIds, paymentStatusIds, shippingStatusIds, + model.CustomerEmail, model.OrderGuid, model.OrderNumber, command.Page - 1, command.PageSize, model.CustomerName); - var gridModel = new GridModel - { - Data = orders.Select(x => - { + gridModel.Data = orders.Select(x => + { var store = _storeService.GetStoreById(x.StoreId); - return new OrderModel - { - Id = x.Id, - OrderNumber = x.GetOrderNumber(), + return new OrderModel + { + Id = x.Id, + OrderNumber = x.GetOrderNumber(), StoreName = (store != null ? store.Name : "".NaIfEmpty()), - OrderTotal = _priceFormatter.FormatPrice(x.OrderTotal, true, false), - OrderStatus = x.OrderStatus.GetLocalizedEnum(_localizationService, _workContext), - PaymentStatus = x.PaymentStatus.GetLocalizedEnum(_localizationService, _workContext), - ShippingStatus = x.ShippingStatus.GetLocalizedEnum(_localizationService, _workContext), + OrderTotal = _priceFormatter.FormatPrice(x.OrderTotal, true, false), + OrderStatus = x.OrderStatus.GetLocalizedEnum(_localizationService, _workContext), + PaymentStatus = x.PaymentStatus.GetLocalizedEnum(_localizationService, _workContext), + ShippingStatus = x.ShippingStatus.GetLocalizedEnum(_localizationService, _workContext), CustomerName = x.BillingAddress.GetFullName(), CustomerEmail = x.BillingAddress.Email, - CreatedOn = _dateTimeHelper.ConvertToUserTime(x.CreatedOnUtc, DateTimeKind.Utc), + CreatedOn = _dateTimeHelper.ConvertToUserTime(x.CreatedOnUtc, DateTimeKind.Utc), HasNewPaymentNotification = x.HasNewPaymentNotification - }; - }), - Total = orders.TotalCount - }; + }; + }); + + gridModel.Total = orders.TotalCount; + + //summary report + //implemented as a workaround described here: http://www.telerik.com/community/forums/aspnet-mvc/grid/gridmodel-aggregates-how-to-use.aspx + var reportSummary = _orderReportService.GetOrderAverageReportLine(model.StoreId, orderStatusIds, + paymentStatusIds, shippingStatusIds, startDateValue, endDateValue, model.CustomerEmail); + + var profit = _orderReportService.ProfitReport(model.StoreId, orderStatusIds, + paymentStatusIds, shippingStatusIds, startDateValue, endDateValue, model.CustomerEmail); + + var aggregator = new OrderModel + { + aggregatorprofit = _priceFormatter.FormatPrice(profit, true, false), + aggregatortax = _priceFormatter.FormatPrice(reportSummary.SumTax, true, false), + aggregatortotal = _priceFormatter.FormatPrice(reportSummary.SumOrders, true, false) + }; + + gridModel.Aggregates = aggregator; + } + else + { + gridModel.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } - //summary report - //implemented as a workaround described here: http://www.telerik.com/community/forums/aspnet-mvc/grid/gridmodel-aggregates-how-to-use.aspx - var reportSummary = _orderReportService.GetOrderAverageReportLine(model.StoreId, orderStatusIds, - paymentStatusIds, shippingStatusIds, startDateValue, endDateValue, model.CustomerEmail); - - var profit = _orderReportService.ProfitReport(model.StoreId, orderStatusIds, - paymentStatusIds, shippingStatusIds, startDateValue, endDateValue, model.CustomerEmail); - - var aggregator = new OrderModel() - { - aggregatorprofit = _priceFormatter.FormatPrice(profit, true, false), - aggregatortax = _priceFormatter.FormatPrice(reportSummary.SumTax, true, false), - aggregatortotal = _priceFormatter.FormatPrice(reportSummary.SumOrders, true, false) - }; - gridModel.Aggregates = aggregator; return new JsonResult { Data = gridModel @@ -1676,36 +1684,46 @@ public ActionResult AddProductToOrder(int orderId) [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult AddProductToOrder(GridCommand command, OrderModel.AddOrderProductModel model) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageOrders)) - return AccessDeniedView(); + var gridModel = new GridModel(); - var gridModel = new GridModel(); - var searchContext = new ProductSearchContext() + if (_permissionService.Authorize(StandardPermissionProvider.ManageOrders)) { - CategoryIds = new List() { model.SearchCategoryId }, - ManufacturerId = model.SearchManufacturerId, - Keywords = model.SearchProductName, - PageIndex = command.Page - 1, - PageSize = command.PageSize, - ShowHidden = true, - ProductType = model.SearchProductTypeId > 0 ? (ProductType?)model.SearchProductTypeId : null - }; + var searchContext = new ProductSearchContext + { + CategoryIds = new List { model.SearchCategoryId }, + ManufacturerId = model.SearchManufacturerId, + Keywords = model.SearchProductName, + PageIndex = command.Page - 1, + PageSize = command.PageSize, + ShowHidden = true, + ProductType = model.SearchProductTypeId > 0 ? (ProductType?)model.SearchProductTypeId : null + }; - var products = _productService.SearchProducts(searchContext); - gridModel.Data = products.Select(x => - { - var productModel = new OrderModel.AddOrderProductModel.ProductModel - { - Id = x.Id, - Name = x.Name, - Sku = x.Sku, - ProductTypeName = x.GetProductTypeLabel(_localizationService), - ProductTypeLabelHint = x.ProductTypeLabelHint - }; + var products = _productService.SearchProducts(searchContext); + + gridModel.Data = products.Select(x => + { + var productModel = new OrderModel.AddOrderProductModel.ProductModel + { + Id = x.Id, + Name = x.Name, + Sku = x.Sku, + ProductTypeName = x.GetProductTypeLabel(_localizationService), + ProductTypeLabelHint = x.ProductTypeLabelHint + }; + + return productModel; + }); + + gridModel.Total = products.TotalCount; + } + else + { + gridModel.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } - return productModel; - }); - gridModel.Total = products.TotalCount; return new JsonResult { Data = gridModel @@ -1983,23 +2001,29 @@ public ActionResult ShipmentList() [GridAction(EnableCustomBinding = true)] public ActionResult ShipmentListSelect(GridCommand command, ShipmentListModel model) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageOrders)) - return AccessDeniedView(); + var gridModel = new GridModel(); - DateTime? startDateValue = (model.StartDate == null) ? null - : (DateTime?)_dateTimeHelper.ConvertToUtcTime(model.StartDate.Value, _dateTimeHelper.CurrentTimeZone); + if (_permissionService.Authorize(StandardPermissionProvider.ManageOrders)) + { + DateTime? startDateValue = (model.StartDate == null) ? null + : (DateTime?)_dateTimeHelper.ConvertToUtcTime(model.StartDate.Value, _dateTimeHelper.CurrentTimeZone); - DateTime? endDateValue = (model.EndDate == null) ? null - :(DateTime?)_dateTimeHelper.ConvertToUtcTime(model.EndDate.Value, _dateTimeHelper.CurrentTimeZone).AddDays(1); + DateTime? endDateValue = (model.EndDate == null) ? null + : (DateTime?)_dateTimeHelper.ConvertToUtcTime(model.EndDate.Value, _dateTimeHelper.CurrentTimeZone).AddDays(1); + + //load shipments + var shipments = _shipmentService.GetAllShipments(model.TrackingNumber, startDateValue, endDateValue, command.Page - 1, command.PageSize); + + gridModel.Data = shipments.Select(shipment => PrepareShipmentModel(shipment, false, false)); + gridModel.Total = shipments.TotalCount; + } + else + { + gridModel.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } - //load shipments - var shipments = _shipmentService.GetAllShipments(model.TrackingNumber, startDateValue, endDateValue, - command.Page - 1, command.PageSize); - var gridModel = new GridModel - { - Data = shipments.Select(shipment => PrepareShipmentModel(shipment, false, false)), - Total = shipments.TotalCount - }; return new JsonResult { Data = gridModel @@ -2009,24 +2033,29 @@ public ActionResult ShipmentListSelect(GridCommand command, ShipmentListModel mo [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult ShipmentsSelect(int orderId, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageOrders)) - return AccessDeniedView(); + var model = new GridModel(); - var order = _orderService.GetOrderById(orderId); - if (order == null) - throw new ArgumentException("No order found with the specified id"); + if (_permissionService.Authorize(StandardPermissionProvider.ManageOrders)) + { + var order = _orderService.GetOrderById(orderId); - //shipments - var shipmentModels = new List(); - var shipments = order.Shipments.OrderBy(s => s.CreatedOnUtc).ToList(); - foreach (var shipment in shipments) - shipmentModels.Add(PrepareShipmentModel(shipment, false, false)); + var shipmentModels = new List(); + var shipments = order.Shipments.OrderBy(s => s.CreatedOnUtc).ToList(); - var model = new GridModel - { - Data = shipmentModels, - Total = shipmentModels.Count - }; + foreach (var shipment in shipments) + { + shipmentModels.Add(PrepareShipmentModel(shipment, false, false)); + } + + model.Data = shipmentModels; + model.Total = shipmentModels.Count; + } + else + { + model.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } return new JsonResult { @@ -2311,37 +2340,40 @@ public ActionResult PdfPackagingSlips(bool all, string selectedIds = null) [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult OrderNotesSelect(int orderId, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageOrders)) - return AccessDeniedView(); + var model = new GridModel(); - var order = _orderService.GetOrderById(orderId); - if (order == null) - throw new ArgumentException("No order found with the specified id"); + if (_permissionService.Authorize(StandardPermissionProvider.ManageOrders)) + { + var order = _orderService.GetOrderById(orderId); - var orderNoteModels = new List(); + var orderNoteModels = new List(); - foreach (var orderNote in order.OrderNotes.OrderByDescending(on => on.CreatedOnUtc)) - { - orderNoteModels.Add(new OrderModel.OrderNote - { - Id = orderNote.Id, - OrderId = orderNote.OrderId, - DisplayToCustomer = orderNote.DisplayToCustomer, - Note = orderNote.FormatOrderNoteText(), - CreatedOn = _dateTimeHelper.ConvertToUserTime(orderNote.CreatedOnUtc, DateTimeKind.Utc) - }); - } + foreach (var orderNote in order.OrderNotes.OrderByDescending(on => on.CreatedOnUtc)) + { + orderNoteModels.Add(new OrderModel.OrderNote + { + Id = orderNote.Id, + OrderId = orderNote.OrderId, + DisplayToCustomer = orderNote.DisplayToCustomer, + Note = orderNote.FormatOrderNoteText(), + CreatedOn = _dateTimeHelper.ConvertToUserTime(orderNote.CreatedOnUtc, DateTimeKind.Utc) + }); + } - var model = new GridModel - { - Data = orderNoteModels, - Total = orderNoteModels.Count - }; + model.Data = orderNoteModels; + model.Total = orderNoteModels.Count; - if (order.HasNewPaymentNotification) + if (order.HasNewPaymentNotification) + { + order.HasNewPaymentNotification = false; + _orderService.UpdateOrder(order); + } + } + else { - order.HasNewPaymentNotification = false; - _orderService.UpdateOrder(order); + model.Data = Enumerable.Empty(); + + NotifyAccessDenied(); } return new JsonResult @@ -2385,17 +2417,13 @@ public ActionResult OrderNoteAdd(int orderId, bool displayToCustomer, string mes [GridAction(EnableCustomBinding = true)] public ActionResult OrderNoteDelete(int orderId, int orderNoteId, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageOrders)) - return AccessDeniedView(); - - var order = _orderService.GetOrderById(orderId); - if (order == null) - throw new ArgumentException("No order found with the specified id"); + if (_permissionService.Authorize(StandardPermissionProvider.ManageOrders)) + { + var order = _orderService.GetOrderById(orderId); + var orderNote = order.OrderNotes.Where(on => on.Id == orderNoteId).FirstOrDefault(); - var orderNote = order.OrderNotes.Where(on => on.Id == orderNoteId).FirstOrDefault(); - if (orderNote == null) - throw new ArgumentException("No order note found with the specified id"); - _orderService.DeleteOrderNote(orderNote); + _orderService.DeleteOrderNote(orderNote); + } return OrderNotesSelect(orderId, command); } @@ -2433,12 +2461,14 @@ protected IList GetBestsellersBriefReportModel(int r return model; } - public ActionResult BestsellersBriefReportByQuantity() + + public ActionResult BestsellersBriefReportByQuantity() { var model = GetBestsellersBriefReportModel(5, 1); return PartialView(model); } - [GridAction(EnableCustomBinding = true)] + + [GridAction(EnableCustomBinding = true)] public ActionResult BestsellersBriefReportByQuantityList(GridCommand command) { var model = GetBestsellersBriefReportModel(5, 1); @@ -2452,12 +2482,14 @@ public ActionResult BestsellersBriefReportByQuantityList(GridCommand command) Data = gridModel }; } - public ActionResult BestsellersBriefReportByAmount() + + public ActionResult BestsellersBriefReportByAmount() { var model = GetBestsellersBriefReportModel(5, 2); return PartialView(model); } - [GridAction(EnableCustomBinding = true)] + + [GridAction(EnableCustomBinding = true)] public ActionResult BestsellersBriefReportByAmountList(GridCommand command) { var model = GetBestsellersBriefReportModel(5, 2); @@ -2496,27 +2528,29 @@ public ActionResult BestsellersReport() return View(model); } - [GridAction(EnableCustomBinding = true)] + + [GridAction(EnableCustomBinding = true)] public ActionResult BestsellersReportList(GridCommand command, BestsellersReportModel model) { DateTime? startDateValue = (model.StartDate == null) ? null - : (DateTime?)_dateTimeHelper.ConvertToUtcTime(model.StartDate.Value, _dateTimeHelper.CurrentTimeZone); + : (DateTime?)_dateTimeHelper.ConvertToUtcTime(model.StartDate.Value, _dateTimeHelper.CurrentTimeZone); DateTime? endDateValue = (model.EndDate == null) ? null - : (DateTime?)_dateTimeHelper.ConvertToUtcTime(model.EndDate.Value, _dateTimeHelper.CurrentTimeZone).AddDays(1); + : (DateTime?)_dateTimeHelper.ConvertToUtcTime(model.EndDate.Value, _dateTimeHelper.CurrentTimeZone).AddDays(1); OrderStatus? orderStatus = model.OrderStatusId > 0 ? (OrderStatus?)(model.OrderStatusId) : null; PaymentStatus? paymentStatus = model.PaymentStatusId > 0 ? (PaymentStatus?)(model.PaymentStatusId) : null; var items = _orderReportService.BestSellersReport(0, startDateValue, endDateValue, orderStatus, paymentStatus, null, model.BillingCountryId, 100, 2, true); + var gridModel = new GridModel { Data = items.Select(x => { var product = _productService.GetProductById(x.ProductId); - var m = new BestsellersReportLineModel() + var m = new BestsellersReportLineModel { ProductId = x.ProductId, TotalAmount = _priceFormatter.FormatPrice(x.TotalAmount, true, false), @@ -2533,6 +2567,7 @@ public ActionResult BestsellersReportList(GridCommand command, BestsellersReport }), Total = items.Count }; + return new JsonResult { Data = gridModel @@ -2546,17 +2581,18 @@ public ActionResult NeverSoldReport() var model = new NeverSoldReportModel(); return View(model); } - [GridAction(EnableCustomBinding = true)] + + [GridAction(EnableCustomBinding = true)] public ActionResult NeverSoldReportList(GridCommand command, NeverSoldReportModel model) { DateTime? startDateValue = (model.StartDate == null) ? null - : (DateTime?)_dateTimeHelper.ConvertToUtcTime(model.StartDate.Value, _dateTimeHelper.CurrentTimeZone); + : (DateTime?)_dateTimeHelper.ConvertToUtcTime(model.StartDate.Value, _dateTimeHelper.CurrentTimeZone); DateTime? endDateValue = (model.EndDate == null) ? null - : (DateTime?)_dateTimeHelper.ConvertToUtcTime(model.EndDate.Value, _dateTimeHelper.CurrentTimeZone).AddDays(1); + : (DateTime?)_dateTimeHelper.ConvertToUtcTime(model.EndDate.Value, _dateTimeHelper.CurrentTimeZone).AddDays(1); - var items = _orderReportService.ProductsNeverSold(startDateValue, endDateValue, - command.Page - 1, command.PageSize, true); + var items = _orderReportService.ProductsNeverSold(startDateValue, endDateValue, command.Page - 1, command.PageSize, true); + var gridModel = new GridModel { Data = items.Select(x => @@ -2572,6 +2608,7 @@ public ActionResult NeverSoldReportList(GridCommand command, NeverSoldReportMode }), Total = items.TotalCount }; + return new JsonResult { Data = gridModel @@ -2680,13 +2717,15 @@ protected virtual IList GetOrderIncompleteReport return model; } - [ChildActionOnly] + + [ChildActionOnly] public ActionResult OrderIncompleteReport() { var model = GetOrderIncompleteReportModel(); return PartialView(model); } - [GridAction(EnableCustomBinding = true)] + + [GridAction(EnableCustomBinding = true)] public ActionResult OrderIncompleteReportList(GridCommand command) { var model = GetOrderIncompleteReportModel(); diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/PollController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/PollController.cs index c6c6abac89..efbf8ad4ad 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/PollController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/PollController.cs @@ -103,24 +103,36 @@ public ActionResult List() [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult List(GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManagePolls)) - return AccessDeniedView(); + var gridModel = new GridModel(); + + if (_permissionService.Authorize(StandardPermissionProvider.ManagePolls)) + { + var polls = _pollService.GetPolls(0, false, command.Page - 1, command.PageSize, true); + + gridModel.Data = polls.Select(x => + { + var m = x.ToModel(); + + if (x.StartDateUtc.HasValue) + m.StartDate = _dateTimeHelper.ConvertToUserTime(x.StartDateUtc.Value, DateTimeKind.Utc); + + if (x.EndDateUtc.HasValue) + m.EndDate = _dateTimeHelper.ConvertToUserTime(x.EndDateUtc.Value, DateTimeKind.Utc); + + m.LanguageName = x.Language.Name; + + return m; + }); + + gridModel.Total = polls.TotalCount; + } + else + { + gridModel.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } - var polls = _pollService.GetPolls(0, false, command.Page - 1, command.PageSize, true); - var gridModel = new GridModel - { - Data = polls.Select(x => - { - var m = x.ToModel(); - if (x.StartDateUtc.HasValue) - m.StartDate = _dateTimeHelper.ConvertToUserTime(x.StartDateUtc.Value, DateTimeKind.Utc); - if (x.EndDateUtc.HasValue) - m.EndDate = _dateTimeHelper.ConvertToUserTime(x.EndDateUtc.Value, DateTimeKind.Utc); - m.LanguageName = x.Language.Name; - return m; - }), - Total = polls.TotalCount - }; return new JsonResult { Data = gridModel @@ -245,30 +257,35 @@ public ActionResult DeleteConfirmed(int id) [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult PollAnswers(int pollId, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManagePolls)) - return AccessDeniedView(); + var model = new GridModel(); - var poll = _pollService.GetPollById(pollId); - if (poll == null) - throw new ArgumentException("No poll found with the specified id", "pollId"); + if (_permissionService.Authorize(StandardPermissionProvider.ManagePolls)) + { + var poll = _pollService.GetPollById(pollId); + + var answers = poll.PollAnswers.OrderBy(x => x.DisplayOrder).ToList(); + + model.Data = answers.Select(x => + { + return new PollAnswerModel + { + Id = x.Id, + PollId = x.PollId, + Name = x.Name, + NumberOfVotes = x.NumberOfVotes, + DisplayOrder1 = x.DisplayOrder + }; + }); + + model.Total = answers.Count; + } + else + { + model.Data = Enumerable.Empty(); - var answers = poll.PollAnswers.OrderBy(x=>x.DisplayOrder).ToList(); + NotifyAccessDenied(); + } - var model = new GridModel - { - Data = answers.Select(x => - { - return new PollAnswerModel() - { - Id = x.Id, - PollId = x.PollId, - Name = x.Name, - NumberOfVotes = x.NumberOfVotes, - DisplayOrder1 = x.DisplayOrder - }; - }), - Total = answers.Count - }; return new JsonResult { Data = model @@ -279,23 +296,21 @@ public ActionResult PollAnswers(int pollId, GridCommand command) [GridAction(EnableCustomBinding = true)] public ActionResult PollAnswerUpdate(PollAnswerModel model, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManagePolls)) - return AccessDeniedView(); - - if (!ModelState.IsValid) - { - //display the first model error - var modelStateErrors = this.ModelState.Values.SelectMany(x => x.Errors).Select(x => x.ErrorMessage); - return Content(modelStateErrors.FirstOrDefault()); - } + var pollAnswer = _pollService.GetPollAnswerById(model.Id); - var pollAnswer = _pollService.GetPollAnswerById(model.Id); - if (pollAnswer == null) - throw new ArgumentException("No poll answer found with the specified id", "id"); + if (_permissionService.Authorize(StandardPermissionProvider.ManagePolls)) + { + if (!ModelState.IsValid) + { + var modelStateErrors = this.ModelState.Values.SelectMany(x => x.Errors).Select(x => x.ErrorMessage); + return Content(modelStateErrors.FirstOrDefault()); + } + + pollAnswer.Name = model.Name; + pollAnswer.DisplayOrder = model.DisplayOrder1; - pollAnswer.Name = model.Name; - pollAnswer.DisplayOrder = model.DisplayOrder1; - _pollService.UpdatePoll(pollAnswer.Poll); + _pollService.UpdatePoll(pollAnswer.Poll); + } return PollAnswers(pollAnswer.PollId, command); } @@ -303,44 +318,39 @@ public ActionResult PollAnswerUpdate(PollAnswerModel model, GridCommand command) [GridAction(EnableCustomBinding = true)] public ActionResult PollAnswerAdd(int pollId, PollAnswerModel model, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManagePolls)) - return AccessDeniedView(); - - if (!ModelState.IsValid) - { - //display the first model error - var modelStateErrors = this.ModelState.Values.SelectMany(x => x.Errors).Select(x => x.ErrorMessage); - return Content(modelStateErrors.FirstOrDefault()); - } + if (_permissionService.Authorize(StandardPermissionProvider.ManagePolls)) + { + if (!ModelState.IsValid) + { + var modelStateErrors = this.ModelState.Values.SelectMany(x => x.Errors).Select(x => x.ErrorMessage); + return Content(modelStateErrors.FirstOrDefault()); + } - var poll = _pollService.GetPollById(pollId); - if (poll == null) - throw new ArgumentException("No poll found with the specified id", "pollId"); + var poll = _pollService.GetPollById(pollId); - poll.PollAnswers.Add(new PollAnswer - { - Name = model.Name, - DisplayOrder = model.DisplayOrder1 - }); - _pollService.UpdatePoll(poll); + poll.PollAnswers.Add(new PollAnswer + { + Name = model.Name, + DisplayOrder = model.DisplayOrder1 + }); + + _pollService.UpdatePoll(poll); + } - return PollAnswers(poll.Id, command); + return PollAnswers(pollId, command); } [GridAction(EnableCustomBinding = true)] public ActionResult PollAnswerDelete(int id, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManagePolls)) - return AccessDeniedView(); - - var pollAnswer = _pollService.GetPollAnswerById(id); - if (pollAnswer == null) - throw new ArgumentException("No poll answer found with the specified id", "id"); - - int pollId = pollAnswer.PollId; - _pollService.DeletePollAnswer(pollAnswer); + var pollAnswer = _pollService.GetPollAnswerById(id); + var pollId = pollAnswer.PollId; + if (_permissionService.Authorize(StandardPermissionProvider.ManagePolls)) + { + _pollService.DeletePollAnswer(pollAnswer); + } return PollAnswers(pollId, command); } diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/ProductAttributeController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/ProductAttributeController.cs index 9381bd50ee..ea2a6ae606 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/ProductAttributeController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/ProductAttributeController.cs @@ -91,29 +91,35 @@ public ActionResult List() [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult List(GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); + var gridModel = new GridModel(); + + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + var productAttributes = _productAttributeService.GetAllProductAttributes(); + + gridModel.Data = productAttributes.Select(x => x.ToModel()); + gridModel.Total = productAttributes.Count(); + } + else + { + gridModel.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } - var productAttributes = _productAttributeService.GetAllProductAttributes(); - var gridModel = new GridModel - { - Data = productAttributes.Select(x => x.ToModel()), - Total = productAttributes.Count() - }; return new JsonResult { Data = gridModel }; } - //create public ActionResult Create() { if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) return AccessDeniedView(); var model = new ProductAttributeModel(); - //locales + AddLocales(_languageService, model.Locales); return View(model); } diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/ProductController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/ProductController.cs index e1f0748bfc..1371b0d5c8 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/ProductController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/ProductController.cs @@ -895,67 +895,74 @@ public ActionResult List(ProductListModel model) return View(model); } - [HttpPost, GridAction(EnableCustomBinding = true)] - public ActionResult ProductList(GridCommand command, ProductListModel model) - { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); + [HttpPost, GridAction(EnableCustomBinding = true)] + public ActionResult ProductList(GridCommand command, ProductListModel model) + { + var gridModel = new GridModel(); - var gridModel = new GridModel(); - var searchContext = new ProductSearchContext - { - ManufacturerId = model.SearchManufacturerId, - StoreId = model.SearchStoreId, - Keywords = model.SearchProductName, - SearchSku = !_catalogSettings.SuppressSkuSearch, - LanguageId = _workContext.WorkingLanguage.Id, - OrderBy = ProductSortingEnum.Position, - PageIndex = command.Page - 1, - PageSize = command.PageSize, - ShowHidden = true, - ProductType = (model.SearchProductTypeId > 0 ? (ProductType?)model.SearchProductTypeId : null), - WithoutCategories = model.SearchWithoutCategories, - WithoutManufacturers = model.SearchWithoutManufacturers, - IsPublished = model.SearchIsPublished, - HomePageProducts = model.SearchHomePageProducts - }; + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + var searchContext = new ProductSearchContext + { + ManufacturerId = model.SearchManufacturerId, + StoreId = model.SearchStoreId, + Keywords = model.SearchProductName, + SearchSku = !_catalogSettings.SuppressSkuSearch, + LanguageId = _workContext.WorkingLanguage.Id, + OrderBy = ProductSortingEnum.Position, + PageIndex = command.Page - 1, + PageSize = command.PageSize, + ShowHidden = true, + ProductType = (model.SearchProductTypeId > 0 ? (ProductType?)model.SearchProductTypeId : null), + WithoutCategories = model.SearchWithoutCategories, + WithoutManufacturers = model.SearchWithoutManufacturers, + IsPublished = model.SearchIsPublished, + HomePageProducts = model.SearchHomePageProducts + }; - if (model.SearchCategoryId > 0) - searchContext.CategoryIds.Add(model.SearchCategoryId); + if (model.SearchCategoryId > 0) + searchContext.CategoryIds.Add(model.SearchCategoryId); - if (command.SortDescriptors != null && command.SortDescriptors.Count > 0) - { - var sort = command.SortDescriptors.First(); - if (sort.Member == "Name") - { - searchContext.OrderBy = (sort.SortDirection == ListSortDirection.Ascending ? ProductSortingEnum.NameAsc : ProductSortingEnum.NameDesc); - } - else if (sort.Member == "Price") - { - searchContext.OrderBy = (sort.SortDirection == ListSortDirection.Ascending ? ProductSortingEnum.PriceAsc : ProductSortingEnum.PriceDesc); - } - else if (sort.Member == "CreatedOn") + if (command.SortDescriptors != null && command.SortDescriptors.Count > 0) { - searchContext.OrderBy = (sort.SortDirection == ListSortDirection.Ascending ? ProductSortingEnum.CreatedOnAsc : ProductSortingEnum.CreatedOn); + var sort = command.SortDescriptors.First(); + if (sort.Member == "Name") + { + searchContext.OrderBy = (sort.SortDirection == ListSortDirection.Ascending ? ProductSortingEnum.NameAsc : ProductSortingEnum.NameDesc); + } + else if (sort.Member == "Price") + { + searchContext.OrderBy = (sort.SortDirection == ListSortDirection.Ascending ? ProductSortingEnum.PriceAsc : ProductSortingEnum.PriceDesc); + } + else if (sort.Member == "CreatedOn") + { + searchContext.OrderBy = (sort.SortDirection == ListSortDirection.Ascending ? ProductSortingEnum.CreatedOnAsc : ProductSortingEnum.CreatedOn); + } } - } - var products = _productService.SearchProducts(searchContext); + var products = _productService.SearchProducts(searchContext); - gridModel.Data = products.Select(x => - { - var productModel = x.ToModel(); - productModel.FullDescription = ""; // Perf - PrepareProductPictureThumbnailModel(productModel, x); + gridModel.Data = products.Select(x => + { + var productModel = x.ToModel(); + productModel.FullDescription = ""; // Perf + PrepareProductPictureThumbnailModel(productModel, x); - productModel.ProductTypeName = x.GetProductTypeLabel(_localizationService); - productModel.UpdatedOn = _dateTimeHelper.ConvertToUserTime(x.UpdatedOnUtc, DateTimeKind.Utc); - productModel.CreatedOn = _dateTimeHelper.ConvertToUserTime(x.CreatedOnUtc, DateTimeKind.Utc); + productModel.ProductTypeName = x.GetProductTypeLabel(_localizationService); + productModel.UpdatedOn = _dateTimeHelper.ConvertToUserTime(x.UpdatedOnUtc, DateTimeKind.Utc); + productModel.CreatedOn = _dateTimeHelper.ConvertToUserTime(x.CreatedOnUtc, DateTimeKind.Utc); - return productModel; - }); + return productModel; + }); + + gridModel.Total = products.TotalCount; + } + else + { + gridModel.Data = Enumerable.Empty(); - gridModel.Total = products.TotalCount; + NotifyAccessDenied(); + } return new JsonResult { @@ -1288,30 +1295,35 @@ public ActionResult CopyProduct(ProductModel model) [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult ProductCategoryList(GridCommand command, int productId) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); + var model = new GridModel(); - var productCategories = _categoryService.GetProductCategoriesByProductId(productId, true); - var productCategoriesModel = productCategories - .Select(x => - { - return new ProductModel.ProductCategoryModel() - { - Id = x.Id, - Category = _categoryService.GetCategoryById(x.CategoryId).GetCategoryBreadCrumb(_categoryService), - ProductId = x.ProductId, - CategoryId = x.CategoryId, - IsFeaturedProduct = x.IsFeaturedProduct, - DisplayOrder = x.DisplayOrder - }; - }) - .ToList(); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + var productCategories = _categoryService.GetProductCategoriesByProductId(productId, true); + var productCategoriesModel = productCategories + .Select(x => + { + return new ProductModel.ProductCategoryModel() + { + Id = x.Id, + Category = _categoryService.GetCategoryById(x.CategoryId).GetCategoryBreadCrumb(_categoryService), + ProductId = x.ProductId, + CategoryId = x.CategoryId, + IsFeaturedProduct = x.IsFeaturedProduct, + DisplayOrder = x.DisplayOrder + }; + }) + .ToList(); - var model = new GridModel - { - Data = productCategoriesModel, - Total = productCategoriesModel.Count - }; + model.Data = productCategoriesModel; + model.Total = productCategoriesModel.Count; + } + else + { + model.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } return new JsonResult { @@ -1322,23 +1334,23 @@ public ActionResult ProductCategoryList(GridCommand command, int productId) [GridAction(EnableCustomBinding = true)] public ActionResult ProductCategoryInsert(GridCommand command, ProductModel.ProductCategoryModel model) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + var productCategory = new ProductCategory + { + ProductId = model.ProductId, + CategoryId = Int32.Parse(model.Category), //use Category property (not CategoryId) because appropriate property is stored in it + IsFeaturedProduct = model.IsFeaturedProduct, + DisplayOrder = model.DisplayOrder + }; - var productCategory = new ProductCategory() - { - ProductId = model.ProductId, - CategoryId = Int32.Parse(model.Category), //use Category property (not CategoryId) because appropriate property is stored in it - IsFeaturedProduct = model.IsFeaturedProduct, - DisplayOrder = model.DisplayOrder - }; - _categoryService.InsertProductCategory(productCategory); + _categoryService.InsertProductCategory(productCategory); - - var mru = new MostRecentlyUsedList(_workContext.CurrentCustomer.GetAttribute(SystemCustomerAttributeNames.MostRecentlyUsedCategories), - model.Category, _catalogSettings.MostRecentlyUsedCategoriesMaxSize); + var mru = new MostRecentlyUsedList(_workContext.CurrentCustomer.GetAttribute(SystemCustomerAttributeNames.MostRecentlyUsedCategories), + model.Category, _catalogSettings.MostRecentlyUsedCategoriesMaxSize); - _genericAttributeService.SaveAttribute(_workContext.CurrentCustomer, SystemCustomerAttributeNames.MostRecentlyUsedCategories, mru.ToString()); + _genericAttributeService.SaveAttribute(_workContext.CurrentCustomer, SystemCustomerAttributeNames.MostRecentlyUsedCategories, mru.ToString()); + } return ProductCategoryList(command, model.ProductId); } @@ -1346,27 +1358,25 @@ public ActionResult ProductCategoryInsert(GridCommand command, ProductModel.Prod [GridAction(EnableCustomBinding = true)] public ActionResult ProductCategoryUpdate(GridCommand command, ProductModel.ProductCategoryModel model) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); + var productCategory = _categoryService.GetProductCategoryById(model.Id); - var productCategory = _categoryService.GetProductCategoryById(model.Id); - if (productCategory == null) - throw new ArgumentException("No product category mapping found with the specified id"); - - bool categoryChanged = (Int32.Parse(model.Category) != productCategory.CategoryId); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + var categoryChanged = (Int32.Parse(model.Category) != productCategory.CategoryId); - //use Category property (not CategoryId) because appropriate property is stored in it - productCategory.CategoryId = Int32.Parse(model.Category); - productCategory.IsFeaturedProduct = model.IsFeaturedProduct; - productCategory.DisplayOrder = model.DisplayOrder; - _categoryService.UpdateProductCategory(productCategory); + //use Category property (not CategoryId) because appropriate property is stored in it + productCategory.CategoryId = Int32.Parse(model.Category); + productCategory.IsFeaturedProduct = model.IsFeaturedProduct; + productCategory.DisplayOrder = model.DisplayOrder; + _categoryService.UpdateProductCategory(productCategory); - if (categoryChanged) - { - var mru = new MostRecentlyUsedList(_workContext.CurrentCustomer.GetAttribute(SystemCustomerAttributeNames.MostRecentlyUsedCategories), - model.Category, _catalogSettings.MostRecentlyUsedCategoriesMaxSize); + if (categoryChanged) + { + var mru = new MostRecentlyUsedList(_workContext.CurrentCustomer.GetAttribute(SystemCustomerAttributeNames.MostRecentlyUsedCategories), + model.Category, _catalogSettings.MostRecentlyUsedCategoriesMaxSize); - _genericAttributeService.SaveAttribute(_workContext.CurrentCustomer, SystemCustomerAttributeNames.MostRecentlyUsedCategories, mru.ToString()); + _genericAttributeService.SaveAttribute(_workContext.CurrentCustomer, SystemCustomerAttributeNames.MostRecentlyUsedCategories, mru.ToString()); + } } return ProductCategoryList(command, productCategory.ProductId); @@ -1375,15 +1385,13 @@ public ActionResult ProductCategoryUpdate(GridCommand command, ProductModel.Prod [GridAction(EnableCustomBinding = true)] public ActionResult ProductCategoryDelete(int id, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); - - var productCategory = _categoryService.GetProductCategoryById(id); - if (productCategory == null) - throw new ArgumentException("No product category mapping found with the specified id"); + var productCategory = _categoryService.GetProductCategoryById(id); + var productId = productCategory.ProductId; - var productId = productCategory.ProductId; - _categoryService.DeleteProductCategory(productCategory); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + _categoryService.DeleteProductCategory(productCategory); + } return ProductCategoryList(command, productId); } @@ -1395,30 +1403,35 @@ public ActionResult ProductCategoryDelete(int id, GridCommand command) [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult ProductManufacturerList(GridCommand command, int productId) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); + var model = new GridModel(); - var productManufacturers = _manufacturerService.GetProductManufacturersByProductId(productId, true); - var productManufacturersModel = productManufacturers - .Select(x => - { - return new ProductModel.ProductManufacturerModel() - { - Id = x.Id, - Manufacturer = _manufacturerService.GetManufacturerById(x.ManufacturerId).Name, - ProductId = x.ProductId, - ManufacturerId = x.ManufacturerId, - IsFeaturedProduct = x.IsFeaturedProduct, - DisplayOrder = x.DisplayOrder - }; - }) - .ToList(); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + var productManufacturers = _manufacturerService.GetProductManufacturersByProductId(productId, true); + var productManufacturersModel = productManufacturers + .Select(x => + { + return new ProductModel.ProductManufacturerModel + { + Id = x.Id, + Manufacturer = _manufacturerService.GetManufacturerById(x.ManufacturerId).Name, + ProductId = x.ProductId, + ManufacturerId = x.ManufacturerId, + IsFeaturedProduct = x.IsFeaturedProduct, + DisplayOrder = x.DisplayOrder + }; + }) + .ToList(); - var model = new GridModel - { - Data = productManufacturersModel, - Total = productManufacturersModel.Count - }; + model.Data = productManufacturersModel; + model.Total = productManufacturersModel.Count; + } + else + { + model.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } return new JsonResult { @@ -1429,22 +1442,23 @@ public ActionResult ProductManufacturerList(GridCommand command, int productId) [GridAction(EnableCustomBinding = true)] public ActionResult ProductManufacturerInsert(GridCommand command, ProductModel.ProductManufacturerModel model) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + var productManufacturer = new ProductManufacturer + { + ProductId = model.ProductId, + ManufacturerId = Int32.Parse(model.Manufacturer), //use Manufacturer property (not ManufacturerId) because appropriate property is stored in it + IsFeaturedProduct = model.IsFeaturedProduct, + DisplayOrder = model.DisplayOrder + }; - var productManufacturer = new ProductManufacturer() - { - ProductId = model.ProductId, - ManufacturerId = Int32.Parse(model.Manufacturer), //use Manufacturer property (not ManufacturerId) because appropriate property is stored in it - IsFeaturedProduct = model.IsFeaturedProduct, - DisplayOrder = model.DisplayOrder - }; - _manufacturerService.InsertProductManufacturer(productManufacturer); + _manufacturerService.InsertProductManufacturer(productManufacturer); - var mru = new MostRecentlyUsedList(_workContext.CurrentCustomer.GetAttribute(SystemCustomerAttributeNames.MostRecentlyUsedManufacturers), - model.Manufacturer, _catalogSettings.MostRecentlyUsedManufacturersMaxSize); + var mru = new MostRecentlyUsedList(_workContext.CurrentCustomer.GetAttribute(SystemCustomerAttributeNames.MostRecentlyUsedManufacturers), + model.Manufacturer, _catalogSettings.MostRecentlyUsedManufacturersMaxSize); - _genericAttributeService.SaveAttribute(_workContext.CurrentCustomer, SystemCustomerAttributeNames.MostRecentlyUsedManufacturers, mru.ToString()); + _genericAttributeService.SaveAttribute(_workContext.CurrentCustomer, SystemCustomerAttributeNames.MostRecentlyUsedManufacturers, mru.ToString()); + } return ProductManufacturerList(command, model.ProductId); } @@ -1452,27 +1466,26 @@ public ActionResult ProductManufacturerInsert(GridCommand command, ProductModel. [GridAction(EnableCustomBinding = true)] public ActionResult ProductManufacturerUpdate(GridCommand command, ProductModel.ProductManufacturerModel model) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); + var productManufacturer = _manufacturerService.GetProductManufacturerById(model.Id); - var productManufacturer = _manufacturerService.GetProductManufacturerById(model.Id); - if (productManufacturer == null) - throw new ArgumentException("No product manufacturer mapping found with the specified id"); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + var manufacturerChanged = (Int32.Parse(model.Manufacturer) != productManufacturer.ManufacturerId); - bool manufacturerChanged = (Int32.Parse(model.Manufacturer) != productManufacturer.ManufacturerId); + //use Manufacturer property (not ManufacturerId) because appropriate property is stored in it + productManufacturer.ManufacturerId = Int32.Parse(model.Manufacturer); + productManufacturer.IsFeaturedProduct = model.IsFeaturedProduct; + productManufacturer.DisplayOrder = model.DisplayOrder; - //use Manufacturer property (not ManufacturerId) because appropriate property is stored in it - productManufacturer.ManufacturerId = Int32.Parse(model.Manufacturer); - productManufacturer.IsFeaturedProduct = model.IsFeaturedProduct; - productManufacturer.DisplayOrder = model.DisplayOrder; - _manufacturerService.UpdateProductManufacturer(productManufacturer); + _manufacturerService.UpdateProductManufacturer(productManufacturer); - if (manufacturerChanged) - { - var mru = new MostRecentlyUsedList(_workContext.CurrentCustomer.GetAttribute(SystemCustomerAttributeNames.MostRecentlyUsedManufacturers), - model.Manufacturer, _catalogSettings.MostRecentlyUsedManufacturersMaxSize); + if (manufacturerChanged) + { + var mru = new MostRecentlyUsedList(_workContext.CurrentCustomer.GetAttribute(SystemCustomerAttributeNames.MostRecentlyUsedManufacturers), + model.Manufacturer, _catalogSettings.MostRecentlyUsedManufacturersMaxSize); - _genericAttributeService.SaveAttribute(_workContext.CurrentCustomer, SystemCustomerAttributeNames.MostRecentlyUsedManufacturers, mru.ToString()); + _genericAttributeService.SaveAttribute(_workContext.CurrentCustomer, SystemCustomerAttributeNames.MostRecentlyUsedManufacturers, mru.ToString()); + } } return ProductManufacturerList(command, productManufacturer.ProductId); @@ -1481,15 +1494,13 @@ public ActionResult ProductManufacturerUpdate(GridCommand command, ProductModel. [GridAction(EnableCustomBinding = true)] public ActionResult ProductManufacturerDelete(int id, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); + var productManufacturer = _manufacturerService.GetProductManufacturerById(id); + var productId = productManufacturer.ProductId; - var productManufacturer = _manufacturerService.GetProductManufacturerById(id); - if (productManufacturer == null) - throw new ArgumentException("No product manufacturer mapping found with the specified id"); - - var productId = productManufacturer.ProductId; - _manufacturerService.DeleteProductManufacturer(productManufacturer); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + _manufacturerService.DeleteProductManufacturer(productManufacturer); + } return ProductManufacturerList(command, productId); } @@ -1501,34 +1512,39 @@ public ActionResult ProductManufacturerDelete(int id, GridCommand command) [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult RelatedProductList(GridCommand command, int productId) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); + var model = new GridModel(); - var relatedProducts = _productService.GetRelatedProductsByProductId1(productId, true); - var relatedProductsModel = relatedProducts - .Select(x => - { - var product2 = _productService.GetProductById(x.ProductId2); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + var relatedProducts = _productService.GetRelatedProductsByProductId1(productId, true); + var relatedProductsModel = relatedProducts + .Select(x => + { + var product2 = _productService.GetProductById(x.ProductId2); - return new ProductModel.RelatedProductModel() - { - Id = x.Id, - ProductId2 = x.ProductId2, - Product2Name = product2.Name, - ProductTypeName = product2.GetProductTypeLabel(_localizationService), - ProductTypeLabelHint = product2.ProductTypeLabelHint, - DisplayOrder = x.DisplayOrder, - Product2Sku = product2.Sku, - Product2Published = product2.Published - }; - }) - .ToList(); + return new ProductModel.RelatedProductModel() + { + Id = x.Id, + ProductId2 = x.ProductId2, + Product2Name = product2.Name, + ProductTypeName = product2.GetProductTypeLabel(_localizationService), + ProductTypeLabelHint = product2.ProductTypeLabelHint, + DisplayOrder = x.DisplayOrder, + Product2Sku = product2.Sku, + Product2Published = product2.Published + }; + }) + .ToList(); - var model = new GridModel - { - Data = relatedProductsModel, - Total = relatedProductsModel.Count - }; + model.Data = relatedProductsModel; + model.Total = relatedProductsModel.Count; + } + else + { + model.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } return new JsonResult { @@ -1539,15 +1555,13 @@ public ActionResult RelatedProductList(GridCommand command, int productId) [GridAction(EnableCustomBinding = true)] public ActionResult RelatedProductUpdate(GridCommand command, ProductModel.RelatedProductModel model) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); - - var relatedProduct = _productService.GetRelatedProductById(model.Id); - if (relatedProduct == null) - throw new ArgumentException("No related product found with the specified id"); + var relatedProduct = _productService.GetRelatedProductById(model.Id); - relatedProduct.DisplayOrder = model.DisplayOrder; - _productService.UpdateRelatedProduct(relatedProduct); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + relatedProduct.DisplayOrder = model.DisplayOrder; + _productService.UpdateRelatedProduct(relatedProduct); + } return RelatedProductList(command, relatedProduct.ProductId1); } @@ -1555,15 +1569,13 @@ public ActionResult RelatedProductUpdate(GridCommand command, ProductModel.Relat [GridAction(EnableCustomBinding = true)] public ActionResult RelatedProductDelete(int id, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); - - var relatedProduct = _productService.GetRelatedProductById(id); - if (relatedProduct == null) - throw new ArgumentException("No related product found with the specified id"); + var relatedProduct = _productService.GetRelatedProductById(id); + var productId = relatedProduct.ProductId1; - var productId = relatedProduct.ProductId1; - _productService.DeleteRelatedProduct(relatedProduct); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + _productService.DeleteRelatedProduct(relatedProduct); + } return RelatedProductList(command, productId); } @@ -1623,36 +1635,45 @@ public ActionResult RelatedProductAddPopup(int productId) [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult RelatedProductAddPopupList(GridCommand command, ProductModel.AddRelatedProductModel model) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); + var gridModel = new GridModel(); - var gridModel = new GridModel(); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + var ctx = new ProductSearchContext(); - var ctx = new ProductSearchContext(); + if (model.SearchCategoryId > 0) + ctx.CategoryIds.Add(model.SearchCategoryId); - if (model.SearchCategoryId > 0) - ctx.CategoryIds.Add(model.SearchCategoryId); + ctx.ManufacturerId = model.SearchManufacturerId; + ctx.StoreId = model.SearchStoreId; + ctx.Keywords = model.SearchProductName; + ctx.SearchSku = !_catalogSettings.SuppressSkuSearch; + ctx.LanguageId = _workContext.WorkingLanguage.Id; + ctx.OrderBy = ProductSortingEnum.Position; + ctx.PageIndex = command.Page - 1; + ctx.PageSize = command.PageSize; + ctx.ShowHidden = true; + ctx.ProductType = model.SearchProductTypeId > 0 ? (ProductType?)model.SearchProductTypeId : null; - ctx.ManufacturerId = model.SearchManufacturerId; - ctx.StoreId = model.SearchStoreId; - ctx.Keywords = model.SearchProductName; - ctx.SearchSku = !_catalogSettings.SuppressSkuSearch; - ctx.LanguageId = _workContext.WorkingLanguage.Id; - ctx.OrderBy = ProductSortingEnum.Position; - ctx.PageIndex = command.Page - 1; - ctx.PageSize = command.PageSize; - ctx.ShowHidden = true; - ctx.ProductType = model.SearchProductTypeId > 0 ? (ProductType?)model.SearchProductTypeId : null; + var products = _productService.SearchProducts(ctx); - var products = _productService.SearchProducts(ctx); - gridModel.Data = products.Select(x => + gridModel.Data = products.Select(x => + { + var productModel = x.ToModel(); + productModel.ProductTypeName = x.GetProductTypeLabel(_localizationService); + + return productModel; + }); + + gridModel.Total = products.TotalCount; + } + else { - var productModel = x.ToModel(); - productModel.ProductTypeName = x.GetProductTypeLabel(_localizationService); + gridModel.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } - return productModel; - }); - gridModel.Total = products.TotalCount; return new JsonResult { Data = gridModel @@ -1732,33 +1753,38 @@ public ActionResult CreateAllMutuallyRelatedProducts(int productId) [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult CrossSellProductList(GridCommand command, int productId) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); + var model = new GridModel(); - var crossSellProducts = _productService.GetCrossSellProductsByProductId1(productId, true); - var crossSellProductsModel = crossSellProducts - .Select(x => - { - var product2 = _productService.GetProductById(x.ProductId2); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + var crossSellProducts = _productService.GetCrossSellProductsByProductId1(productId, true); + var crossSellProductsModel = crossSellProducts + .Select(x => + { + var product2 = _productService.GetProductById(x.ProductId2); - return new ProductModel.CrossSellProductModel() - { - Id = x.Id, - ProductId2 = x.ProductId2, - Product2Name = product2.Name, - ProductTypeName = product2.GetProductTypeLabel(_localizationService), - ProductTypeLabelHint = product2.ProductTypeLabelHint, - Product2Sku = product2.Sku, - Product2Published = product2.Published - }; - }) - .ToList(); + return new ProductModel.CrossSellProductModel + { + Id = x.Id, + ProductId2 = x.ProductId2, + Product2Name = product2.Name, + ProductTypeName = product2.GetProductTypeLabel(_localizationService), + ProductTypeLabelHint = product2.ProductTypeLabelHint, + Product2Sku = product2.Sku, + Product2Published = product2.Published + }; + }) + .ToList(); - var model = new GridModel - { - Data = crossSellProductsModel, - Total = crossSellProductsModel.Count - }; + model.Data = crossSellProductsModel; + model.Total = crossSellProductsModel.Count; + } + else + { + model.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } return new JsonResult { @@ -1769,15 +1795,13 @@ public ActionResult CrossSellProductList(GridCommand command, int productId) [GridAction(EnableCustomBinding = true)] public ActionResult CrossSellProductDelete(int id, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); - - var crossSellProduct = _productService.GetCrossSellProductById(id); - if (crossSellProduct == null) - throw new ArgumentException("No cross-sell product found with the specified id"); + var crossSellProduct = _productService.GetCrossSellProductById(id); + var productId = crossSellProduct.ProductId1; - var productId = crossSellProduct.ProductId1; - _productService.DeleteCrossSellProduct(crossSellProduct); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + _productService.DeleteCrossSellProduct(crossSellProduct); + } return CrossSellProductList(command, productId); } @@ -1837,37 +1861,45 @@ public ActionResult CrossSellProductAddPopup(int productId) [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult CrossSellProductAddPopupList(GridCommand command, ProductModel.AddCrossSellProductModel model) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); + var gridModel = new GridModel(); - var gridModel = new GridModel(); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + var ctx = new ProductSearchContext(); - var ctx = new ProductSearchContext(); + if (model.SearchCategoryId > 0) + ctx.CategoryIds.Add(model.SearchCategoryId); - if (model.SearchCategoryId > 0) - ctx.CategoryIds.Add(model.SearchCategoryId); + ctx.ManufacturerId = model.SearchManufacturerId; + ctx.StoreId = model.SearchStoreId; + ctx.Keywords = model.SearchProductName; + ctx.SearchSku = !_catalogSettings.SuppressSkuSearch; + ctx.LanguageId = _workContext.WorkingLanguage.Id; + ctx.OrderBy = ProductSortingEnum.Position; + ctx.PageIndex = command.Page - 1; + ctx.PageSize = command.PageSize; + ctx.ShowHidden = true; + ctx.ProductType = model.SearchProductTypeId > 0 ? (ProductType?)model.SearchProductTypeId : null; - ctx.ManufacturerId = model.SearchManufacturerId; - ctx.StoreId = model.SearchStoreId; - ctx.Keywords = model.SearchProductName; - ctx.SearchSku = !_catalogSettings.SuppressSkuSearch; - ctx.LanguageId = _workContext.WorkingLanguage.Id; - ctx.OrderBy = ProductSortingEnum.Position; - ctx.PageIndex = command.Page - 1; - ctx.PageSize = command.PageSize; - ctx.ShowHidden = true; - ctx.ProductType = model.SearchProductTypeId > 0 ? (ProductType?)model.SearchProductTypeId : null; + var products = _productService.SearchProducts(ctx); - var products = _productService.SearchProducts(ctx); + gridModel.Data = products.Select(x => + { + var productModel = x.ToModel(); + productModel.ProductTypeName = x.GetProductTypeLabel(_localizationService); + + return productModel; + }); - gridModel.Data = products.Select(x => + gridModel.Total = products.TotalCount; + } + else { - var productModel = x.ToModel(); - productModel.ProductTypeName = x.GetProductTypeLabel(_localizationService); + gridModel.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } - return productModel; - }); - gridModel.Total = products.TotalCount; return new JsonResult { Data = gridModel @@ -1946,38 +1978,43 @@ public ActionResult CreateAllMutuallyCrossSellProducts(int productId) [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult AssociatedProductList(GridCommand command, int productId) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); + var model = new GridModel(); - var searchContext = new ProductSearchContext() + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) { - ParentGroupedProductId = productId, - PageSize = int.MaxValue, - ShowHidden = true - }; - - var associatedProducts = _productService.SearchProducts(searchContext); - var associatedProductsModel = associatedProducts - .Select(x => + var searchContext = new ProductSearchContext { - return new ProductModel.AssociatedProductModel() + ParentGroupedProductId = productId, + PageSize = int.MaxValue, + ShowHidden = true + }; + + var associatedProducts = _productService.SearchProducts(searchContext); + var associatedProductsModel = associatedProducts + .Select(x => { - Id = x.Id, - ProductName = x.Name, - ProductTypeName = x.GetProductTypeLabel(_localizationService), - ProductTypeLabelHint = x.ProductTypeLabelHint, - DisplayOrder = x.DisplayOrder, - Sku = x.Sku, - Published = x.Published - }; - }) - .ToList(); + return new ProductModel.AssociatedProductModel + { + Id = x.Id, + ProductName = x.Name, + ProductTypeName = x.GetProductTypeLabel(_localizationService), + ProductTypeLabelHint = x.ProductTypeLabelHint, + DisplayOrder = x.DisplayOrder, + Sku = x.Sku, + Published = x.Published + }; + }) + .ToList(); - var model = new GridModel + model.Data = associatedProductsModel; + model.Total = associatedProductsModel.Count; + } + else { - Data = associatedProductsModel, - Total = associatedProductsModel.Count - }; + model.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } return new JsonResult { @@ -1988,15 +2025,13 @@ public ActionResult AssociatedProductList(GridCommand command, int productId) [GridAction(EnableCustomBinding = true)] public ActionResult AssociatedProductUpdate(GridCommand command, ProductModel.AssociatedProductModel model) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); - var associatedProduct = _productService.GetProductById(model.Id); - if (associatedProduct == null) - throw new ArgumentException("No associated product found with the specified id"); - associatedProduct.DisplayOrder = model.DisplayOrder; - _productService.UpdateProduct(associatedProduct); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + associatedProduct.DisplayOrder = model.DisplayOrder; + _productService.UpdateProduct(associatedProduct); + } return AssociatedProductList(command, associatedProduct.ParentGroupedProductId); } @@ -2004,19 +2039,16 @@ public ActionResult AssociatedProductUpdate(GridCommand command, ProductModel.As [GridAction(EnableCustomBinding = true)] public ActionResult AssociatedProductDelete(int id, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); - var product = _productService.GetProductById(id); - if (product == null) - throw new ArgumentException("No associated product found with the specified id"); - var originalParentGroupedProductId = product.ParentGroupedProductId; - product.ParentGroupedProductId = 0; - _productService.UpdateProduct(product); - - return AssociatedProductList(command, originalParentGroupedProductId); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + product.ParentGroupedProductId = 0; + _productService.UpdateProduct(product); + } + + return AssociatedProductList(command, originalParentGroupedProductId); } public ActionResult AssociatedProductAddPopup(int productId) @@ -2057,33 +2089,41 @@ public ActionResult AssociatedProductAddPopup(int productId) [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult AssociatedProductAddPopupList(GridCommand command, ProductModel.AddAssociatedProductModel model) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); + var gridModel = new GridModel(); - var searchContext = new ProductSearchContext() - { - CategoryIds = new List() { model.SearchCategoryId }, - ManufacturerId = model.SearchManufacturerId, - StoreId = model.SearchStoreId, - Keywords = model.SearchProductName, - SearchSku = !_catalogSettings.SuppressSkuSearch, - PageIndex = command.Page - 1, - PageSize = command.PageSize, - ShowHidden = true, - ProductType = model.SearchProductTypeId > 0 ? (ProductType?)model.SearchProductTypeId : null - }; + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + var searchContext = new ProductSearchContext + { + CategoryIds = new List() { model.SearchCategoryId }, + ManufacturerId = model.SearchManufacturerId, + StoreId = model.SearchStoreId, + Keywords = model.SearchProductName, + SearchSku = !_catalogSettings.SuppressSkuSearch, + PageIndex = command.Page - 1, + PageSize = command.PageSize, + ShowHidden = true, + ProductType = model.SearchProductTypeId > 0 ? (ProductType?)model.SearchProductTypeId : null + }; + + var products = _productService.SearchProducts(searchContext); - var products = _productService.SearchProducts(searchContext); + gridModel.Data = products.Select(x => + { + var productModel = x.ToModel(); + productModel.ProductTypeName = x.GetProductTypeLabel(_localizationService); - var gridModel = new GridModel(); - gridModel.Data = products.Select(x => + return productModel; + }); + + gridModel.Total = products.TotalCount; + } + else { - var productModel = x.ToModel(); - productModel.ProductTypeName = x.GetProductTypeLabel(_localizationService); + gridModel.Data = Enumerable.Empty(); - return productModel; - }); - gridModel.Total = products.TotalCount; + NotifyAccessDenied(); + } return new JsonResult { @@ -2222,34 +2262,39 @@ private void SaveFilteredAttributes(ProductBundleItem bundleItem, FormCollection [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult BundleItemList(GridCommand command, int productId) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); + var model = new GridModel(); - var bundleItems = _productService.GetBundleItems(productId, true).Select(x => x.Item); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + var bundleItems = _productService.GetBundleItems(productId, true).Select(x => x.Item); - var bundleItemsModel = bundleItems.Select(x => - { - return new ProductModel.BundleItemModel() + var bundleItemsModel = bundleItems.Select(x => { - Id = x.Id, - ProductId = x.Product.Id, - ProductName = x.Product.Name, - ProductTypeName = x.Product.GetProductTypeLabel(_localizationService), - ProductTypeLabelHint = x.Product.ProductTypeLabelHint, - Sku = x.Product.Sku, - Quantity = x.Quantity, - Discount = x.Discount, - DisplayOrder = x.DisplayOrder, - Visible = x.Visible, - Published = x.Published - }; - }).ToList(); + return new ProductModel.BundleItemModel + { + Id = x.Id, + ProductId = x.Product.Id, + ProductName = x.Product.Name, + ProductTypeName = x.Product.GetProductTypeLabel(_localizationService), + ProductTypeLabelHint = x.Product.ProductTypeLabelHint, + Sku = x.Product.Sku, + Quantity = x.Quantity, + Discount = x.Discount, + DisplayOrder = x.DisplayOrder, + Visible = x.Visible, + Published = x.Published + }; + }).ToList(); - var model = new GridModel() + model.Data = bundleItemsModel; + model.Total = bundleItemsModel.Count; + } + else { - Data = bundleItemsModel, - Total = bundleItemsModel.Count - }; + model.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } return new JsonResult { Data = model }; } @@ -2257,15 +2302,12 @@ public ActionResult BundleItemList(GridCommand command, int productId) [GridAction(EnableCustomBinding = true)] public ActionResult BundleItemDelete(int id, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); - var bundleItem = _productService.GetBundleItemById(id); - if (bundleItem == null) - throw new ArgumentException("No product bundle item found with the specified id"); - - _productService.DeleteBundleItem(bundleItem); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + _productService.DeleteBundleItem(bundleItem); + } return BundleItemList(command, bundleItem.BundleProductId); } @@ -2369,34 +2411,42 @@ public ActionResult BundleItemAddPopup(string btnId, string formId, ProductModel [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult BundleItemAddPopupList(GridCommand command, ProductModel.AddBundleItemModel model) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); + var gridModel = new GridModel(); - var searchContext = new ProductSearchContext() - { - CategoryIds = new List() { model.SearchCategoryId }, - ManufacturerId = model.SearchManufacturerId, - StoreId = model.SearchStoreId, - Keywords = model.SearchProductName, - SearchSku = !_catalogSettings.SuppressSkuSearch, - PageIndex = command.Page - 1, - PageSize = command.PageSize, - ShowHidden = true, - ProductType = model.SearchProductTypeId > 0 ? (ProductType?)model.SearchProductTypeId : null - }; + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + var searchContext = new ProductSearchContext + { + CategoryIds = new List { model.SearchCategoryId }, + ManufacturerId = model.SearchManufacturerId, + StoreId = model.SearchStoreId, + Keywords = model.SearchProductName, + SearchSku = !_catalogSettings.SuppressSkuSearch, + PageIndex = command.Page - 1, + PageSize = command.PageSize, + ShowHidden = true, + ProductType = model.SearchProductTypeId > 0 ? (ProductType?)model.SearchProductTypeId : null + }; - var products = _productService.SearchProducts(searchContext); + var products = _productService.SearchProducts(searchContext); - var gridModel = new GridModel(); - gridModel.Data = products.Select(x => + gridModel.Data = products.Select(x => + { + var productModel = x.ToModel(); + productModel.ProductTypeName = x.GetProductTypeLabel(_localizationService); + productModel.ProductSelectCheckboxClass = (!x.CanBeBundleItem() ? " hide" : ""); + + return productModel; + }); + + gridModel.Total = products.TotalCount; + } + else { - var productModel = x.ToModel(); - productModel.ProductTypeName = x.GetProductTypeLabel(_localizationService); - productModel.ProductSelectCheckboxClass = (!x.CanBeBundleItem() ? " hide" : ""); + gridModel.Data = Enumerable.Empty(); - return productModel; - }); - gridModel.Total = products.TotalCount; + NotifyAccessDenied(); + } return new JsonResult { @@ -2498,29 +2548,34 @@ public ActionResult ProductPictureAdd(int pictureId, int displayOrder, int produ [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult ProductPictureList(GridCommand command, int productId) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); + var model = new GridModel(); - var productPictures = _productService.GetProductPicturesByProductId(productId); - var productPicturesModel = productPictures - .Select(x => - { - return new ProductModel.ProductPictureModel() - { - Id = x.Id, - ProductId = x.ProductId, - PictureId = x.PictureId, - PictureUrl = _pictureService.GetPictureUrl(x.PictureId), - DisplayOrder = x.DisplayOrder - }; - }) - .ToList(); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + var productPictures = _productService.GetProductPicturesByProductId(productId); + var productPicturesModel = productPictures + .Select(x => + { + return new ProductModel.ProductPictureModel + { + Id = x.Id, + ProductId = x.ProductId, + PictureId = x.PictureId, + PictureUrl = _pictureService.GetPictureUrl(x.PictureId), + DisplayOrder = x.DisplayOrder + }; + }) + .ToList(); - var model = new GridModel - { - Data = productPicturesModel, - Total = productPicturesModel.Count - }; + model.Data = productPicturesModel; + model.Total = productPicturesModel.Count; + } + else + { + model.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } return new JsonResult { @@ -2531,15 +2586,13 @@ public ActionResult ProductPictureList(GridCommand command, int productId) [GridAction(EnableCustomBinding = true)] public ActionResult ProductPictureUpdate(ProductModel.ProductPictureModel model, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); + var productPicture = _productService.GetProductPictureById(model.Id); - var productPicture = _productService.GetProductPictureById(model.Id); - if (productPicture == null) - throw new ArgumentException("No product picture found with the specified id"); - - productPicture.DisplayOrder = model.DisplayOrder; - _productService.UpdateProductPicture(productPicture); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + productPicture.DisplayOrder = model.DisplayOrder; + _productService.UpdateProductPicture(productPicture); + } return ProductPictureList(command, productPicture.ProductId); } @@ -2547,18 +2600,16 @@ public ActionResult ProductPictureUpdate(ProductModel.ProductPictureModel model, [GridAction(EnableCustomBinding = true)] public ActionResult ProductPictureDelete(int id, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); + var productPicture = _productService.GetProductPictureById(id); + var productId = productPicture.ProductId; - var productPicture = _productService.GetProductPictureById(id); - if (productPicture == null) - throw new ArgumentException("No product picture found with the specified id"); - - var productId = productPicture.ProductId; - _productService.DeleteProductPicture(productPicture); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + _productService.DeleteProductPicture(productPicture); - var picture = _pictureService.GetPictureById(productPicture.PictureId); - _pictureService.DeletePicture(picture); + var picture = _pictureService.GetPictureById(productPicture.PictureId); + _pictureService.DeletePicture(picture); + } return ProductPictureList(command, productId); } @@ -2589,51 +2640,56 @@ public ActionResult ProductSpecificationAttributeAdd(int specificationAttributeO [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult ProductSpecAttrList(GridCommand command, int productId) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); - - var productrSpecs = _specificationAttributeService.GetProductSpecificationAttributesByProductId(productId); + var model = new GridModel(); - var productrSpecsModel = productrSpecs - .Select(x => - { - var psaModel = new ProductSpecificationAttributeModel() - { - Id = x.Id, - SpecificationAttributeName = x.SpecificationAttributeOption.SpecificationAttribute.Name, - SpecificationAttributeOptionName = x.SpecificationAttributeOption.Name, - SpecificationAttributeOptionAttributeId = x.SpecificationAttributeOption.SpecificationAttributeId, - SpecificationAttributeOptionId = x.SpecificationAttributeOptionId, - AllowFiltering = x.AllowFiltering, - ShowOnProductPage = x.ShowOnProductPage, - DisplayOrder = x.DisplayOrder - }; - return psaModel; - }) - .ToList(); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + var productrSpecs = _specificationAttributeService.GetProductSpecificationAttributesByProductId(productId); - foreach(var attr in productrSpecsModel) { + var productrSpecsModel = productrSpecs + .Select(x => + { + var psaModel = new ProductSpecificationAttributeModel + { + Id = x.Id, + SpecificationAttributeName = x.SpecificationAttributeOption.SpecificationAttribute.Name, + SpecificationAttributeOptionName = x.SpecificationAttributeOption.Name, + SpecificationAttributeOptionAttributeId = x.SpecificationAttributeOption.SpecificationAttributeId, + SpecificationAttributeOptionId = x.SpecificationAttributeOptionId, + AllowFiltering = x.AllowFiltering, + ShowOnProductPage = x.ShowOnProductPage, + DisplayOrder = x.DisplayOrder + }; + return psaModel; + }) + .ToList(); - var options = _specificationAttributeService.GetSpecificationAttributeOptionsBySpecificationAttribute(attr.SpecificationAttributeOptionAttributeId); + foreach (var attr in productrSpecsModel) + { + var options = _specificationAttributeService.GetSpecificationAttributeOptionsBySpecificationAttribute(attr.SpecificationAttributeOptionAttributeId); - foreach(var option in options) { + foreach (var option in options) + { + attr.SpecificationAttributeOptions.Add(new ProductSpecificationAttributeModel.SpecificationAttributeOption + { + id = option.Id, + name = option.Name, + text = option.Name + }); + } - attr.SpecificationAttributeOptions.Add(new ProductSpecificationAttributeModel.SpecificationAttributeOption() - { - id = option.Id, - name = option.Name, - text = option.Name - }); - } + attr.SpecificationAttributeOptionsJsonString = JsonConvert.SerializeObject(attr.SpecificationAttributeOptions); + } - attr.SpecificationAttributeOptionsJsonString = JsonConvert.SerializeObject(attr.SpecificationAttributeOptions); - } + model.Data = productrSpecsModel; + model.Total = productrSpecsModel.Count; + } + else + { + model.Data = Enumerable.Empty(); - var model = new GridModel - { - Data = productrSpecsModel, - Total = productrSpecsModel.Count - }; + NotifyAccessDenied(); + } return new JsonResult { @@ -2642,17 +2698,17 @@ public ActionResult ProductSpecAttrList(GridCommand command, int productId) } [GridAction(EnableCustomBinding = true)] - public ActionResult ProductSpecAttrUpdate(int psaId, ProductSpecificationAttributeModel model, - GridCommand command) + public ActionResult ProductSpecAttrUpdate(int psaId, ProductSpecificationAttributeModel model, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); + var psa = _specificationAttributeService.GetProductSpecificationAttributeById(psaId); - var psa = _specificationAttributeService.GetProductSpecificationAttributeById(psaId); - psa.AllowFiltering = model.AllowFiltering; - psa.ShowOnProductPage = model.ShowOnProductPage; - psa.DisplayOrder = model.DisplayOrder; - _specificationAttributeService.UpdateProductSpecificationAttribute(psa); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + psa.AllowFiltering = model.AllowFiltering; + psa.ShowOnProductPage = model.ShowOnProductPage; + psa.DisplayOrder = model.DisplayOrder; + _specificationAttributeService.UpdateProductSpecificationAttribute(psa); + } return ProductSpecAttrList(command, psa.ProductId); } @@ -2660,15 +2716,13 @@ public ActionResult ProductSpecAttrUpdate(int psaId, ProductSpecificationAttribu [GridAction(EnableCustomBinding = true)] public ActionResult ProductSpecAttrDelete(int psaId, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); - - var psa = _specificationAttributeService.GetProductSpecificationAttributeById(psaId); - if (psa == null) - throw new ArgumentException("No specification attribute found with the specified id"); + var psa = _specificationAttributeService.GetProductSpecificationAttributeById(psaId); + var productId = psa.ProductId; - var productId = psa.ProductId; - _specificationAttributeService.DeleteProductSpecificationAttribute(psa); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + _specificationAttributeService.DeleteProductSpecificationAttribute(psa); + } return ProductSpecAttrList(command, productId); } @@ -2688,28 +2742,33 @@ public ActionResult ProductTags() [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult ProductTags(GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); + var model = new GridModel(); + + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + var tags = _productTagService.GetAllProductTags() + .OrderByDescending(x => _productTagService.GetProductCount(x.Id, 0)) + .Select(x => + { + return new ProductTagModel + { + Id = x.Id, + Name = x.Name, + ProductCount = _productTagService.GetProductCount(x.Id, 0) + }; + }) + .ForCommand(command); + + model.Data = tags.PagedForCommand(command); + model.Total = tags.Count(); + } + else + { + model.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } - var tags = _productTagService.GetAllProductTags() - //order by product count - .OrderByDescending(x => _productTagService.GetProductCount(x.Id, 0)) - .Select(x => - { - return new ProductTagModel() - { - Id = x.Id, - Name = x.Name, - ProductCount = _productTagService.GetProductCount(x.Id, 0) - }; - }) - .ForCommand(command); - - var model = new GridModel - { - Data = tags.PagedForCommand(command), - Total = tags.Count() - }; return new JsonResult { Data = model @@ -2719,13 +2778,12 @@ public ActionResult ProductTags(GridCommand command) [GridAction(EnableCustomBinding = true)] public ActionResult ProductTagDelete(int id, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + var tag = _productTagService.GetProductTagById(id); - var tag = _productTagService.GetProductTagById(id); - if (tag == null) - throw new ArgumentException("No product tag found with the specified id"); - _productTagService.DeleteProductTag(tag); + _productTagService.DeleteProductTag(tag); + } return ProductTags(command); } @@ -2799,21 +2857,29 @@ public ActionResult LowStockReport() [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult LowStockReportList(GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); + var model = new GridModel(); - var allProducts = _productService.GetLowStockProducts(); - var model = new GridModel() + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) { - Data = allProducts.PagedForCommand(command).Select(x => + var allProducts = _productService.GetLowStockProducts(); + + model.Data = allProducts.PagedForCommand(command).Select(x => { var productModel = x.ToModel(); productModel.ProductTypeName = x.GetProductTypeLabel(_localizationService); return productModel; - }), - Total = allProducts.Count - }; + }); + + model.Total = allProducts.Count; + } + else + { + model.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } + return new JsonResult { Data = model @@ -2860,47 +2926,54 @@ public ActionResult BulkEdit() [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult BulkEditSelect(GridCommand command, BulkEditListModel model) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); + var gridModel = new GridModel(); - var searchContext = new ProductSearchContext + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) { - StoreId = model.SearchStoreId, - ManufacturerId = model.SearchManufacturerId, - Keywords = model.SearchProductName, - SearchSku = !_catalogSettings.SuppressSkuSearch, - PageIndex = command.Page - 1, - PageSize = command.PageSize, - ShowHidden = true, - ProductType = model.SearchProductTypeId > 0 ? (ProductType?)model.SearchProductTypeId : null - }; + var searchContext = new ProductSearchContext + { + StoreId = model.SearchStoreId, + ManufacturerId = model.SearchManufacturerId, + Keywords = model.SearchProductName, + SearchSku = !_catalogSettings.SuppressSkuSearch, + PageIndex = command.Page - 1, + PageSize = command.PageSize, + ShowHidden = true, + ProductType = model.SearchProductTypeId > 0 ? (ProductType?)model.SearchProductTypeId : null + }; - if (model.SearchCategoryId > 0) - searchContext.CategoryIds.Add(model.SearchCategoryId); + if (model.SearchCategoryId > 0) + searchContext.CategoryIds.Add(model.SearchCategoryId); - var products = _productService.SearchProducts(searchContext); - var gridModel = new GridModel(); + var products = _productService.SearchProducts(searchContext); - gridModel.Data = products.Select(x => - { - var productModel = new BulkEditProductModel() + gridModel.Data = products.Select(x => { - Id = x.Id, - Name = x.Name, - ProductTypeName = x.GetProductTypeLabel(_localizationService), - ProductTypeLabelHint = x.ProductTypeLabelHint, - Sku = x.Sku, - OldPrice = x.OldPrice, - Price = x.Price, - ManageInventoryMethod = x.ManageInventoryMethod.GetLocalizedEnum(_localizationService, _workContext.WorkingLanguage.Id), - StockQuantity = x.StockQuantity, - Published = x.Published - }; + var productModel = new BulkEditProductModel + { + Id = x.Id, + Name = x.Name, + ProductTypeName = x.GetProductTypeLabel(_localizationService), + ProductTypeLabelHint = x.ProductTypeLabelHint, + Sku = x.Sku, + OldPrice = x.OldPrice, + Price = x.Price, + ManageInventoryMethod = x.ManageInventoryMethod.GetLocalizedEnum(_localizationService, _workContext.WorkingLanguage.Id), + StockQuantity = x.StockQuantity, + Published = x.Published + }; - return productModel; - }); + return productModel; + }); + + gridModel.Total = products.TotalCount; + } + else + { + gridModel.Data = Enumerable.Empty(); - gridModel.Total = products.TotalCount; + NotifyAccessDenied(); + } return new JsonResult { @@ -2915,39 +2988,39 @@ public ActionResult BulkEditSave(GridCommand command, [Bind(Prefix = "deleted")]IEnumerable deletedProducts, BulkEditListModel model) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); - - if (updatedProducts != null) + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) { - foreach (var pModel in updatedProducts) + if (updatedProducts != null) { - //update - var product = _productService.GetProductById(pModel.Id); - if (product != null) + foreach (var pModel in updatedProducts) { - product.Sku = pModel.Sku; - product.Price = pModel.Price; - product.OldPrice = pModel.OldPrice; - product.StockQuantity = pModel.StockQuantity; - product.Published = pModel.Published; + var product = _productService.GetProductById(pModel.Id); + if (product != null) + { + product.Sku = pModel.Sku; + product.Price = pModel.Price; + product.OldPrice = pModel.OldPrice; + product.StockQuantity = pModel.StockQuantity; + product.Published = pModel.Published; - _productService.UpdateProduct(product); + _productService.UpdateProduct(product); + } } } - } - if (deletedProducts != null) - { - foreach (var pModel in deletedProducts) + if (deletedProducts != null) { - var product = _productService.GetProductById(pModel.Id); - if (product != null) + foreach (var pModel in deletedProducts) { - _productService.DeleteProduct(product); + var product = _productService.GetProductById(pModel.Id); + if (product != null) + { + _productService.DeleteProduct(product); + } } } } + return BulkEditSelect(command, model); } @@ -2958,64 +3031,67 @@ public ActionResult BulkEditSave(GridCommand command, [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult TierPriceList(GridCommand command, int productId) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); - - var product = _productService.GetProductById(productId); - if (product == null) - throw new ArgumentException("No product variant found with the specified id"); + var model = new GridModel(); - var allStores = _services.StoreService.GetAllStores(); - var allCustomerRoles = _customerService.GetAllCustomerRoles(true); - string allRolesString = T("Admin.Catalog.Products.TierPrices.Fields.CustomerRole.AllRoles"); - string allStoresString = T("Admin.Common.StoresAll"); - string deletedString = "[{0}]".FormatInvariant(T("Admin.Common.Deleted")); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + var product = _productService.GetProductById(productId); - var tierPricesModel = product.TierPrices - .OrderBy(x => x.StoreId) - .ThenBy(x => x.Quantity) - .ThenBy(x => x.CustomerRoleId) - .Select(x => - { - var tierPriceModel = new ProductModel.TierPriceModel + var allStores = _services.StoreService.GetAllStores(); + var allCustomerRoles = _customerService.GetAllCustomerRoles(true); + string allRolesString = T("Admin.Catalog.Products.TierPrices.Fields.CustomerRole.AllRoles"); + string allStoresString = T("Admin.Common.StoresAll"); + string deletedString = "[{0}]".FormatInvariant(T("Admin.Common.Deleted")); + + var tierPricesModel = product.TierPrices + .OrderBy(x => x.StoreId) + .ThenBy(x => x.Quantity) + .ThenBy(x => x.CustomerRoleId) + .Select(x => { - Id = x.Id, - StoreId = x.StoreId, - ProductId = x.ProductId, - CustomerRoleId = x.CustomerRoleId ?? 0, - Quantity = x.Quantity, - Price1 = x.Price - }; + var tierPriceModel = new ProductModel.TierPriceModel + { + Id = x.Id, + StoreId = x.StoreId, + ProductId = x.ProductId, + CustomerRoleId = x.CustomerRoleId ?? 0, + Quantity = x.Quantity, + Price1 = x.Price + }; - if (x.CustomerRoleId.HasValue) - { - var role = allCustomerRoles.FirstOrDefault(r => r.Id == x.CustomerRoleId.Value); - tierPriceModel.CustomerRole = (role == null ? allRolesString : role.Name); - } - else - { - tierPriceModel.CustomerRole = allRolesString; - } + if (x.CustomerRoleId.HasValue) + { + var role = allCustomerRoles.FirstOrDefault(r => r.Id == x.CustomerRoleId.Value); + tierPriceModel.CustomerRole = (role == null ? allRolesString : role.Name); + } + else + { + tierPriceModel.CustomerRole = allRolesString; + } - if (x.StoreId > 0) - { - var store = allStores.FirstOrDefault(s => s.Id == x.StoreId); - tierPriceModel.Store = (store == null ? deletedString : store.Name); - } - else - { - tierPriceModel.Store = allStoresString; - } + if (x.StoreId > 0) + { + var store = allStores.FirstOrDefault(s => s.Id == x.StoreId); + tierPriceModel.Store = (store == null ? deletedString : store.Name); + } + else + { + tierPriceModel.Store = allStoresString; + } - return tierPriceModel; - }) - .ToList(); + return tierPriceModel; + }) + .ToList(); - var model = new GridModel + model.Data = tierPricesModel; + model.Total = tierPricesModel.Count; + } + else { - Data = tierPricesModel, - Total = tierPricesModel.Count - }; + model.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } return new JsonResult { @@ -3026,27 +3102,26 @@ public ActionResult TierPriceList(GridCommand command, int productId) [GridAction(EnableCustomBinding = true)] public ActionResult TierPriceInsert(GridCommand command, ProductModel.TierPriceModel model) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + var product = _productService.GetProductById(model.ProductId); - var product = _productService.GetProductById(model.ProductId); - if (product == null) - throw new ArgumentException("No product found with the specified id"); + var tierPrice = new TierPrice + { + ProductId = model.ProductId, + // use Store property (not Store propertyId) because appropriate property is stored in it + StoreId = model.Store.ToInt(), + // use CustomerRole property (not CustomerRoleId) because appropriate property is stored in it + CustomerRoleId = model.CustomerRole.IsNumeric() && Int32.Parse(model.CustomerRole) != 0 ? Int32.Parse(model.CustomerRole) : (int?)null, + Quantity = model.Quantity, + Price = model.Price1 + }; - var tierPrice = new TierPrice() - { - ProductId = model.ProductId, - // use Store property (not Store propertyId) because appropriate property is stored in it - StoreId = model.Store.ToInt(), - // use CustomerRole property (not CustomerRoleId) because appropriate property is stored in it - CustomerRoleId = model.CustomerRole.IsNumeric() && Int32.Parse(model.CustomerRole) != 0 ? Int32.Parse(model.CustomerRole) : (int?)null, - Quantity = model.Quantity, - Price = model.Price1 - }; - _productService.InsertTierPrice(tierPrice); + _productService.InsertTierPrice(tierPrice); - //update "HasTierPrices" property - _productService.UpdateHasTierPricesProperty(product); + //update "HasTierPrices" property + _productService.UpdateHasTierPricesProperty(product); + } return TierPriceList(command, model.ProductId); } @@ -3054,20 +3129,19 @@ public ActionResult TierPriceInsert(GridCommand command, ProductModel.TierPriceM [GridAction(EnableCustomBinding = true)] public ActionResult TierPriceUpdate(GridCommand command, ProductModel.TierPriceModel model) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); - var tierPrice = _productService.GetTierPriceById(model.Id); - if (tierPrice == null) - throw new ArgumentException("No tier price found with the specified id"); - //use Store property (not Store propertyId) because appropriate property is stored in it - tierPrice.StoreId = model.Store.ToInt(); - //use CustomerRole property (not CustomerRoleId) because appropriate property is stored in it - tierPrice.CustomerRoleId = model.CustomerRole.IsNumeric() && Int32.Parse(model.CustomerRole) != 0 ? Int32.Parse(model.CustomerRole) : (int?)null; - tierPrice.Quantity = model.Quantity; - tierPrice.Price = model.Price1; - _productService.UpdateTierPrice(tierPrice); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + //use Store property (not Store propertyId) because appropriate property is stored in it + tierPrice.StoreId = model.Store.ToInt(); + //use CustomerRole property (not CustomerRoleId) because appropriate property is stored in it + tierPrice.CustomerRoleId = model.CustomerRole.IsNumeric() && Int32.Parse(model.CustomerRole) != 0 ? Int32.Parse(model.CustomerRole) : (int?)null; + tierPrice.Quantity = model.Quantity; + tierPrice.Price = model.Price1; + + _productService.UpdateTierPrice(tierPrice); + } return TierPriceList(command, tierPrice.ProductId); } @@ -3075,22 +3149,18 @@ public ActionResult TierPriceUpdate(GridCommand command, ProductModel.TierPriceM [GridAction(EnableCustomBinding = true)] public ActionResult TierPriceDelete(int id, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); - var tierPrice = _productService.GetTierPriceById(id); - if (tierPrice == null) - throw new ArgumentException("No tier price found with the specified id"); - var productId = tierPrice.ProductId; - var product = _productService.GetProductById(productId); - if (product == null) - throw new ArgumentException("No product found with the specified id"); - _productService.DeleteTierPrice(tierPrice); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + var product = _productService.GetProductById(productId); + + _productService.DeleteTierPrice(tierPrice); - //update "HasTierPrices" property - _productService.UpdateHasTierPricesProperty(product); + //update "HasTierPrices" property + _productService.UpdateHasTierPricesProperty(product); + } return TierPriceList(command, productId); } @@ -3102,40 +3172,45 @@ public ActionResult TierPriceDelete(int id, GridCommand command) [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult ProductVariantAttributeList(GridCommand command, int productId) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); + var model = new GridModel(); - var productVariantAttributes = _productAttributeService.GetProductVariantAttributesByProductId(productId); - var productVariantAttributesModel = productVariantAttributes - .Select(x => - { - var pvaModel = new ProductModel.ProductVariantAttributeModel() + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + var productVariantAttributes = _productAttributeService.GetProductVariantAttributesByProductId(productId); + var productVariantAttributesModel = productVariantAttributes + .Select(x => { - Id = x.Id, - ProductId = x.ProductId, - ProductAttribute = _productAttributeService.GetProductAttributeById(x.ProductAttributeId).Name, - ProductAttributeId = x.ProductAttributeId, - TextPrompt = x.TextPrompt, - IsRequired = x.IsRequired, - AttributeControlType = x.AttributeControlType.GetLocalizedEnum(_localizationService, _workContext), - AttributeControlTypeId = x.AttributeControlTypeId, - DisplayOrder1 = x.DisplayOrder - }; + var pvaModel = new ProductModel.ProductVariantAttributeModel + { + Id = x.Id, + ProductId = x.ProductId, + ProductAttribute = _productAttributeService.GetProductAttributeById(x.ProductAttributeId).Name, + ProductAttributeId = x.ProductAttributeId, + TextPrompt = x.TextPrompt, + IsRequired = x.IsRequired, + AttributeControlType = x.AttributeControlType.GetLocalizedEnum(_localizationService, _workContext), + AttributeControlTypeId = x.AttributeControlTypeId, + DisplayOrder1 = x.DisplayOrder + }; - if (x.ShouldHaveValues()) - { - pvaModel.ViewEditUrl = Url.Action("EditAttributeValues", "Product", new { productVariantAttributeId = x.Id }); - pvaModel.ViewEditText = string.Format(_localizationService.GetResource("Admin.Catalog.Products.ProductVariantAttributes.Attributes.Values.ViewLink"), x.ProductVariantAttributeValues != null ? x.ProductVariantAttributeValues.Count : 0); - } - return pvaModel; - }) - .ToList(); + if (x.ShouldHaveValues()) + { + pvaModel.ViewEditUrl = Url.Action("EditAttributeValues", "Product", new { productVariantAttributeId = x.Id }); + pvaModel.ViewEditText = string.Format(_localizationService.GetResource("Admin.Catalog.Products.ProductVariantAttributes.Attributes.Values.ViewLink"), x.ProductVariantAttributeValues != null ? x.ProductVariantAttributeValues.Count : 0); + } + return pvaModel; + }) + .ToList(); - var model = new GridModel + model.Data = productVariantAttributesModel; + model.Total = productVariantAttributesModel.Count; + } + else { - Data = productVariantAttributesModel, - Total = productVariantAttributesModel.Count - }; + model.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } return new JsonResult { @@ -3146,19 +3221,20 @@ public ActionResult ProductVariantAttributeList(GridCommand command, int product [GridAction(EnableCustomBinding = true)] public ActionResult ProductVariantAttributeInsert(GridCommand command, ProductModel.ProductVariantAttributeModel model) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); - - var pva = new ProductVariantAttribute() + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) { - ProductId = model.ProductId, - ProductAttributeId = Int32.Parse(model.ProductAttribute), //use ProductAttribute property (not ProductAttributeId) because appropriate property is stored in it - TextPrompt = model.TextPrompt, - IsRequired = model.IsRequired, - AttributeControlTypeId = Int32.Parse(model.AttributeControlType), //use AttributeControlType property (not AttributeControlTypeId) because appropriate property is stored in it - DisplayOrder = model.DisplayOrder1 - }; - _productAttributeService.InsertProductVariantAttribute(pva); + var pva = new ProductVariantAttribute + { + ProductId = model.ProductId, + ProductAttributeId = Int32.Parse(model.ProductAttribute), //use ProductAttribute property (not ProductAttributeId) because appropriate property is stored in it + TextPrompt = model.TextPrompt, + IsRequired = model.IsRequired, + AttributeControlTypeId = Int32.Parse(model.AttributeControlType), //use AttributeControlType property (not AttributeControlTypeId) because appropriate property is stored in it + DisplayOrder = model.DisplayOrder1 + }; + + _productAttributeService.InsertProductVariantAttribute(pva); + } return ProductVariantAttributeList(command, model.ProductId); } @@ -3166,21 +3242,20 @@ public ActionResult ProductVariantAttributeInsert(GridCommand command, ProductMo [GridAction(EnableCustomBinding = true)] public ActionResult ProductVariantAttributeUpdate(GridCommand command, ProductModel.ProductVariantAttributeModel model) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); - var pva = _productAttributeService.GetProductVariantAttributeById(model.Id); - if (pva == null) - throw new ArgumentException("No product variant attribute found with the specified id"); - //use ProductAttribute property (not ProductAttributeId) because appropriate property is stored in it - pva.ProductAttributeId = Int32.Parse(model.ProductAttribute); - pva.TextPrompt = model.TextPrompt; - pva.IsRequired = model.IsRequired; - //use AttributeControlType property (not AttributeControlTypeId) because appropriate property is stored in it - pva.AttributeControlTypeId = Int32.Parse(model.AttributeControlType); - pva.DisplayOrder = model.DisplayOrder1; - _productAttributeService.UpdateProductVariantAttribute(pva); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + //use ProductAttribute property (not ProductAttributeId) because appropriate property is stored in it + pva.ProductAttributeId = Int32.Parse(model.ProductAttribute); + pva.TextPrompt = model.TextPrompt; + pva.IsRequired = model.IsRequired; + //use AttributeControlType property (not AttributeControlTypeId) because appropriate property is stored in it + pva.AttributeControlTypeId = Int32.Parse(model.AttributeControlType); + pva.DisplayOrder = model.DisplayOrder1; + + _productAttributeService.UpdateProductVariantAttribute(pva); + } return ProductVariantAttributeList(command, pva.ProductId); } @@ -3188,16 +3263,13 @@ public ActionResult ProductVariantAttributeUpdate(GridCommand command, ProductMo [GridAction(EnableCustomBinding = true)] public ActionResult ProductVariantAttributeDelete(int id, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); - var pva = _productAttributeService.GetProductVariantAttributeById(id); - if (pva == null) - throw new ArgumentException("No product variant attribute found with the specified id"); - var productId = pva.ProductId; - _productAttributeService.DeleteProductVariantAttribute(pva); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + _productAttributeService.DeleteProductVariantAttribute(pva); + } return ProductVariantAttributeList(command, productId); } @@ -3254,22 +3326,19 @@ public ActionResult EditAttributeValues(int productVariantAttributeId) [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult ProductAttributeValueList(int productVariantAttributeId, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); + var gridModel = new GridModel(); - var pva = _productAttributeService.GetProductVariantAttributeById(productVariantAttributeId); - if (pva == null) - throw new ArgumentException("No product variant attribute found with the specified id"); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + var pva = _productAttributeService.GetProductVariantAttributeById(productVariantAttributeId); - var values = _productAttributeService.GetProductVariantAttributeValues(productVariantAttributeId); + var values = _productAttributeService.GetProductVariantAttributeValues(productVariantAttributeId); - var gridModel = new GridModel - { - Data = values.Select(x => + gridModel.Data = values.Select(x => { var linkedProduct = _productService.GetProductById(x.LinkedProductId); - var model = new ProductModel.ProductVariantAttributeValueModel() + var model = new ProductModel.ProductVariantAttributeValueModel { Id = x.Id, ProductVariantAttributeId = x.ProductVariantAttributeId, @@ -3300,9 +3369,17 @@ public ActionResult ProductAttributeValueList(int productVariantAttributeId, Gri } return model; - }), - Total = values.Count() - }; + }); + + gridModel.Total = values.Count(); + } + else + { + gridModel.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } + return new JsonResult { Data = gridModel @@ -3493,14 +3570,12 @@ public ActionResult ProductAttributeValueEditPopup(string btnId, string formId, [GridAction(EnableCustomBinding = true)] public ActionResult ProductAttributeValueDelete(int pvavId, int productVariantAttributeId, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); - - var pvav = _productAttributeService.GetProductVariantAttributeValueById(pvavId); - if (pvav == null) - throw new ArgumentException("No product variant attribute value found with the specified id"); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + var pvav = _productAttributeService.GetProductVariantAttributeValueById(pvavId); - _productAttributeService.DeleteProductVariantAttributeValue(pvav); + _productAttributeService.DeleteProductVariantAttributeValue(pvav); + } return ProductAttributeValueList(productVariantAttributeId, command); } @@ -3543,33 +3618,41 @@ public ActionResult ProductAttributeValueLinkagePopup() [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult ProductAttributeValueLinkagePopupList(GridCommand command, ProductModel.ProductVariantAttributeValueModel.AddProductLinkageModel model) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); + var gridModel = new GridModel(); - var searchContext = new ProductSearchContext() - { - CategoryIds = new List() { model.SearchCategoryId }, - ManufacturerId = model.SearchManufacturerId, - StoreId = model.SearchStoreId, - Keywords = model.SearchProductName, - SearchSku = !_catalogSettings.SuppressSkuSearch, - PageIndex = command.Page - 1, - PageSize = command.PageSize, - ShowHidden = true, - ProductType = model.SearchProductTypeId > 0 ? (ProductType?)model.SearchProductTypeId : null - }; + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + var searchContext = new ProductSearchContext + { + CategoryIds = new List { model.SearchCategoryId }, + ManufacturerId = model.SearchManufacturerId, + StoreId = model.SearchStoreId, + Keywords = model.SearchProductName, + SearchSku = !_catalogSettings.SuppressSkuSearch, + PageIndex = command.Page - 1, + PageSize = command.PageSize, + ShowHidden = true, + ProductType = model.SearchProductTypeId > 0 ? (ProductType?)model.SearchProductTypeId : null + }; + + var products = _productService.SearchProducts(searchContext); + + gridModel.Data = products.Select(x => + { + var productModel = x.ToModel(); + productModel.ProductTypeName = x.GetProductTypeLabel(_localizationService); - var products = _productService.SearchProducts(searchContext); + return productModel; + }); - var gridModel = new GridModel(); - gridModel.Data = products.Select(x => + gridModel.Total = products.TotalCount; + } + else { - var productModel = x.ToModel(); - productModel.ProductTypeName = x.GetProductTypeLabel(_localizationService); + gridModel.Data = Enumerable.Empty(); - return productModel; - }); - gridModel.Total = products.TotalCount; + NotifyAccessDenied(); + } return new JsonResult { @@ -3704,65 +3787,69 @@ private void PrepareDeliveryTimes(ProductVariantAttributeCombinationModel model, [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult ProductVariantAttributeCombinationList(GridCommand command, int productId) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); + var model = new GridModel(); - // TODO: Replace ProductModel.ProductVariantAttributeCombinationModel by AddProductVariantAttributeCombinationModel - // when there's no grid-inline-editing anymore. + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + // TODO: Replace ProductModel.ProductVariantAttributeCombinationModel by AddProductVariantAttributeCombinationModel + // when there's no grid-inline-editing anymore. - var product = _productService.GetProductById(productId); - if (product == null) - throw new ArgumentException("No product found with the specified id"); + var product = _productService.GetProductById(productId); - var allCombinations = _productAttributeService.GetAllProductVariantAttributeCombinations(product.Id, command.Page - 1, command.PageSize); + var allCombinations = _productAttributeService.GetAllProductVariantAttributeCombinations(product.Id, command.Page - 1, command.PageSize); - var productUrlTitle = _localizationService.GetResource("Common.OpenInShop"); - var productSeName = product.GetSeName(); + var productUrlTitle = _localizationService.GetResource("Common.OpenInShop"); + var productSeName = product.GetSeName(); - var productVariantAttributesModel = allCombinations.Select(x => - { - var pvacModel = x.ToModel(); - PrepareProductAttributeCombinationModel(pvacModel, x, product, true); + var productVariantAttributesModel = allCombinations.Select(x => + { + var pvacModel = x.ToModel(); + PrepareProductAttributeCombinationModel(pvacModel, x, product, true); - pvacModel.ProductUrl = _productAttributeParser.GetProductUrlWithAttributes(x.AttributesXml, product.Id, productSeName); - pvacModel.ProductUrlTitle = productUrlTitle; + pvacModel.ProductUrl = _productAttributeParser.GetProductUrlWithAttributes(x.AttributesXml, product.Id, productSeName); + pvacModel.ProductUrlTitle = productUrlTitle; - try - { - var firstAttribute = _productAttributeParser.DeserializeProductVariantAttributes(x.AttributesXml).FirstOrDefault(); - - var attribute = x.Product.ProductVariantAttributes.FirstOrDefault(y => y.Id == firstAttribute.Key); - var attributeValue = attribute.ProductVariantAttributeValues.FirstOrDefault(y => y.Id == int.Parse(firstAttribute.Value.First())); + try + { + var firstAttribute = _productAttributeParser.DeserializeProductVariantAttributes(x.AttributesXml).FirstOrDefault(); - pvacModel.DisplayOrder = attributeValue.DisplayOrder; - } - catch (Exception exc) - { - exc.Dump(); - } + var attribute = x.Product.ProductVariantAttributes.FirstOrDefault(y => y.Id == firstAttribute.Key); + var attributeValue = attribute.ProductVariantAttributeValues.FirstOrDefault(y => y.Id == int.Parse(firstAttribute.Value.First())); - //if (x.IsDefaultCombination) - // pvacModel.AttributesXml = "{0}".FormatWith(pvacModel.AttributesXml); + pvacModel.DisplayOrder = attributeValue.DisplayOrder; + } + catch (Exception exc) + { + exc.Dump(); + } - //warnings - var warnings = _shoppingCartService.GetShoppingCartItemAttributeWarnings( - _workContext.CurrentCustomer, - ShoppingCartType.ShoppingCart, - x.Product, - x.AttributesXml, - combination: x); - - pvacModel.Warnings.AddRange(warnings); + //if (x.IsDefaultCombination) + // pvacModel.AttributesXml = "{0}".FormatWith(pvacModel.AttributesXml); + + //warnings + var warnings = _shoppingCartService.GetShoppingCartItemAttributeWarnings( + _workContext.CurrentCustomer, + ShoppingCartType.ShoppingCart, + x.Product, + x.AttributesXml, + combination: x); - return pvacModel; - }) - .OrderBy(x => x.DisplayOrder).ToList(); + pvacModel.Warnings.AddRange(warnings); - var model = new GridModel + return pvacModel; + }) + .OrderBy(x => x.DisplayOrder) + .ToList(); + + model.Data = productVariantAttributesModel; + model.Total = allCombinations.TotalCount; + } + else { - Data = productVariantAttributesModel, - Total = allCombinations.TotalCount, - }; + model.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } return new JsonResult { @@ -3773,19 +3860,16 @@ public ActionResult ProductVariantAttributeCombinationList(GridCommand command, [GridAction(EnableCustomBinding = true)] public ActionResult ProductVariantAttributeCombinationDelete(int id, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); - var pvac = _productAttributeService.GetProductVariantAttributeCombinationById(id); - if (pvac == null) - throw new ArgumentException("No product variant attribute combination found with the specified id"); - var productId = pvac.ProductId; - _productAttributeService.DeleteProductVariantAttributeCombination(pvac); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + _productAttributeService.DeleteProductVariantAttributeCombination(pvac); - var product = _productService.GetProductById(productId); - _productService.UpdateLowestAttributeCombinationPriceProperty(product); + var product = _productService.GetProductById(productId); + _productService.UpdateLowestAttributeCombinationPriceProperty(product); + } return ProductVariantAttributeCombinationList(command, productId); } diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/ProductReviewController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/ProductReviewController.cs index 9858dc1745..dff5a6de80 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/ProductReviewController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/ProductReviewController.cs @@ -109,34 +109,40 @@ public ActionResult List() [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult List(GridCommand command, ProductReviewListModel model) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); + var gridModel = new GridModel(); - DateTime? createdOnFromValue = (model.CreatedOnFrom == null) ? null - : (DateTime?)_dateTimeHelper.ConvertToUtcTime(model.CreatedOnFrom.Value, _dateTimeHelper.CurrentTimeZone); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + DateTime? createdOnFromValue = (model.CreatedOnFrom == null) ? null + : (DateTime?)_dateTimeHelper.ConvertToUtcTime(model.CreatedOnFrom.Value, _dateTimeHelper.CurrentTimeZone); - DateTime? createdToFromValue = (model.CreatedOnTo == null) ? null - : (DateTime?)_dateTimeHelper.ConvertToUtcTime(model.CreatedOnTo.Value, _dateTimeHelper.CurrentTimeZone).AddDays(1); + DateTime? createdToFromValue = (model.CreatedOnTo == null) ? null + : (DateTime?)_dateTimeHelper.ConvertToUtcTime(model.CreatedOnTo.Value, _dateTimeHelper.CurrentTimeZone).AddDays(1); + + var productReviews = _customerContentService.GetAllCustomerContent(0, null, createdOnFromValue, createdToFromValue); + + gridModel.Data = productReviews.PagedForCommand(command).Select(x => + { + var m = new ProductReviewModel(); + PrepareProductReviewModel(m, x, false, true); + return m; + }); + + gridModel.Total = productReviews.Count; + } + else + { + gridModel.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } - var productReviews = _customerContentService.GetAllCustomerContent(0, null, - createdOnFromValue, createdToFromValue); - var gridModel = new GridModel - { - Data = productReviews.PagedForCommand(command).Select(x => - { - var m = new ProductReviewModel(); - PrepareProductReviewModel(m, x, false, true); - return m; - }), - Total = productReviews.Count, - }; return new JsonResult { Data = gridModel }; } - //edit public ActionResult Edit(int id) { if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) @@ -186,7 +192,6 @@ public ActionResult Edit(ProductReviewModel model, bool continueEditing) return View(model); } - //delete [HttpPost, ActionName("Delete")] public ActionResult DeleteConfirmed(int id) { diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/QueuedEmailController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/QueuedEmailController.cs index 58057c2d80..6bc007e811 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/QueuedEmailController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/QueuedEmailController.cs @@ -53,41 +53,47 @@ public ActionResult List() [GridAction(EnableCustomBinding = true)] public ActionResult QueuedEmailList(GridCommand command, QueuedEmailListModel model) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageMessageQueue)) - return AccessDeniedView(); + var gridModel = new GridModel(); - DateTime? startDateValue = (model.SearchStartDate == null) ? null : (DateTime?)_dateTimeHelper.ConvertToUtcTime(model.SearchStartDate.Value, _dateTimeHelper.CurrentTimeZone); - DateTime? endDateValue = (model.SearchEndDate == null) ? null : (DateTime?)_dateTimeHelper.ConvertToUtcTime(model.SearchEndDate.Value, _dateTimeHelper.CurrentTimeZone).AddDays(1); - - var q = new SearchEmailsQuery + if (_permissionService.Authorize(StandardPermissionProvider.ManageMessageQueue)) { - EndTime = endDateValue, - From = model.SearchFromEmail, - MaxSendTries = model.SearchMaxSentTries, - OrderByLatest = true, - PageIndex = command.Page - 1, - PageSize = command.PageSize, - SendManually = model.SearchSendManually, - StartTime = startDateValue, - To = model.SearchToEmail, - UnsentOnly = model.SearchLoadNotSent - }; - var queuedEmails = _queuedEmailService.SearchEmails(q); + DateTime? startDateValue = (model.SearchStartDate == null) ? null : (DateTime?)_dateTimeHelper.ConvertToUtcTime(model.SearchStartDate.Value, _dateTimeHelper.CurrentTimeZone); + DateTime? endDateValue = (model.SearchEndDate == null) ? null : (DateTime?)_dateTimeHelper.ConvertToUtcTime(model.SearchEndDate.Value, _dateTimeHelper.CurrentTimeZone).AddDays(1); - var gridModel = new GridModel - { - Data = queuedEmails.Select(x => + var q = new SearchEmailsQuery + { + EndTime = endDateValue, + From = model.SearchFromEmail, + MaxSendTries = model.SearchMaxSentTries, + OrderByLatest = true, + PageIndex = command.Page - 1, + PageSize = command.PageSize, + SendManually = model.SearchSendManually, + StartTime = startDateValue, + To = model.SearchToEmail, + UnsentOnly = model.SearchLoadNotSent + }; + var queuedEmails = _queuedEmailService.SearchEmails(q); + + gridModel.Data = queuedEmails.Select(x => { - var m = x.ToModel(); - m.CreatedOn = _dateTimeHelper.ConvertToUserTime(x.CreatedOnUtc, DateTimeKind.Utc); + var m = x.ToModel(); + m.CreatedOn = _dateTimeHelper.ConvertToUserTime(x.CreatedOnUtc, DateTimeKind.Utc); - if (x.SentOnUtc.HasValue) - m.SentOn = _dateTimeHelper.ConvertToUserTime(x.SentOnUtc.Value, DateTimeKind.Utc); + if (x.SentOnUtc.HasValue) + m.SentOn = _dateTimeHelper.ConvertToUserTime(x.SentOnUtc.Value, DateTimeKind.Utc); - return m; - }), - Total = queuedEmails.TotalCount - }; + return m; + }); + + gridModel.Total = queuedEmails.TotalCount; + } + else + { + gridModel.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } return new JsonResult { diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/RecurringPaymentController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/RecurringPaymentController.cs index 39d549fc08..0f4b15968e 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/RecurringPaymentController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/RecurringPaymentController.cs @@ -113,7 +113,6 @@ private void PrepareRecurringPaymentHistoryModel(RecurringPaymentModel.Recurring #region Recurring payment - //list public ActionResult Index() { return RedirectToAction("List"); @@ -131,27 +130,34 @@ public ActionResult List() [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult List(GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageOrders)) - return AccessDeniedView(); + var gridModel = new GridModel(); + + if (_permissionService.Authorize(StandardPermissionProvider.ManageOrders)) + { + var payments = _orderService.SearchRecurringPayments(0, 0, 0, null, true); + + gridModel.Data = payments.PagedForCommand(command).Select(x => + { + var m = new RecurringPaymentModel(); + PrepareRecurringPaymentModel(m, x, false); + return m; + }); + + gridModel.Total = payments.Count; + } + else + { + gridModel.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } - var payments = _orderService.SearchRecurringPayments(0, 0, 0, null, true); - var gridModel = new GridModel - { - Data = payments.PagedForCommand(command).Select(x => - { - var m = new RecurringPaymentModel(); - PrepareRecurringPaymentModel(m, x, false); - return m; - }), - Total = payments.Count, - }; return new JsonResult { Data = gridModel }; } - //edit public ActionResult Edit(int id) { if (!_permissionService.Authorize(StandardPermissionProvider.ManageOrders)) @@ -189,7 +195,6 @@ public ActionResult Edit(RecurringPaymentModel model, bool continueEditing) return continueEditing ? RedirectToAction("Edit", payment.Id) : RedirectToAction("List"); } - //delete [HttpPost, ActionName("Delete")] public ActionResult DeleteConfirmed(int id) { @@ -214,26 +219,30 @@ public ActionResult DeleteConfirmed(int id) [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult HistoryList(int recurringPaymentId, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageOrders)) - return AccessDeniedView(); - - var payment = _orderService.GetRecurringPaymentById(recurringPaymentId); - if (payment == null) - throw new ArgumentException("No recurring payment found with the specified id"); - - var historyModel = payment.RecurringPaymentHistory.OrderBy(x => x.CreatedOnUtc) - .Select(x => - { - var m = new RecurringPaymentModel.RecurringPaymentHistoryModel(); - PrepareRecurringPaymentHistoryModel(m, x); - return m; - }) - .ToList(); - var model = new GridModel - { - Data = historyModel, - Total = historyModel.Count - }; + var model = new GridModel(); + + if (_permissionService.Authorize(StandardPermissionProvider.ManageOrders)) + { + var payment = _orderService.GetRecurringPaymentById(recurringPaymentId); + + var historyModel = payment.RecurringPaymentHistory.OrderBy(x => x.CreatedOnUtc) + .Select(x => + { + var m = new RecurringPaymentModel.RecurringPaymentHistoryModel(); + PrepareRecurringPaymentHistoryModel(m, x); + return m; + }) + .ToList(); + + model.Data = historyModel; + model.Total = historyModel.Count; + } + else + { + model.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } return new JsonResult { diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/ReturnRequestController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/ReturnRequestController.cs index 1180d71fc7..f210fef4fd 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/ReturnRequestController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/ReturnRequestController.cs @@ -171,7 +171,6 @@ private bool PrepareReturnRequestModel(ReturnRequestModel model, ReturnRequest r #region Methods - //list public ActionResult Index() { return RedirectToAction("List"); @@ -191,26 +190,31 @@ public ActionResult List() [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult List(GridCommand command, ReturnRequestListModel model) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageReturnRequests)) - return AccessDeniedView(); + var gridModel = new GridModel(); - var data = new List(); + if (_permissionService.Authorize(StandardPermissionProvider.ManageReturnRequests)) + { + var data = new List(); - var returnRequests = _orderService.SearchReturnRequests(model.SearchStoreId, 0, 0, model.SearchReturnRequestStatus, - command.Page - 1, command.PageSize, model.SearchId ?? 0); + var returnRequests = _orderService.SearchReturnRequests(model.SearchStoreId, 0, 0, model.SearchReturnRequestStatus, + command.Page - 1, command.PageSize, model.SearchId ?? 0); - foreach (var rr in returnRequests) - { - var m = new ReturnRequestModel(); - if (PrepareReturnRequestModel(m, rr, false)) - data.Add(m); - } + foreach (var rr in returnRequests) + { + var m = new ReturnRequestModel(); + if (PrepareReturnRequestModel(m, rr, false)) + data.Add(m); + } - var gridModel = new GridModel + gridModel.Data = data; + gridModel.Total = returnRequests.TotalCount; + } + else { - Data = data, - Total = returnRequests.TotalCount, - }; + gridModel.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } return new JsonResult { @@ -218,7 +222,6 @@ public ActionResult List(GridCommand command, ReturnRequestListModel model) }; } - //edit public ActionResult Edit(int id) { if (!_permissionService.Authorize(StandardPermissionProvider.ManageReturnRequests)) @@ -300,7 +303,6 @@ public ActionResult NotifyCustomer(ReturnRequestModel model) return RedirectToAction("Edit", returnRequest.Id); } - //delete [HttpPost, ActionName("Delete")] public ActionResult DeleteConfirmed(int id) { diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/SettingController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/SettingController.cs index 086be63a26..85ea07067b 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/SettingController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/SettingController.cs @@ -1532,44 +1532,49 @@ public ActionResult AllSettings() [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult AllSettings(GridCommand command) { - if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageSettings)) - return AccessDeniedView(); + var model = new GridModel(); - var stores = _services.StoreService.GetAllStores(); - string allStoresString = _services.Localization.GetResource("Admin.Common.StoresAll"); - - var settings = _services.Settings - .GetAllSettings() - .Select(x => - { - var settingModel = new SettingModel() - { - Id = x.Id, - Name = x.Name, - Value = x.Value, - StoreId = x.StoreId - }; + if (_services.Permissions.Authorize(StandardPermissionProvider.ManageSettings)) + { + var stores = _services.StoreService.GetAllStores(); + string allStoresString = _services.Localization.GetResource("Admin.Common.StoresAll"); - if (x.StoreId == 0) - { - settingModel.Store = allStoresString; - } - else + var settings = _services.Settings + .GetAllSettings() + .Select(x => { - var store = stores.FirstOrDefault(s => s.Id == x.StoreId); - settingModel.Store = store != null ? store.Name : "Unknown"; - } - - return settingModel; - }) - .ForCommand(command) - .ToList(); - - var model = new GridModel - { - Data = settings.PagedForCommand(command), - Total = settings.Count - }; + var settingModel = new SettingModel() + { + Id = x.Id, + Name = x.Name, + Value = x.Value, + StoreId = x.StoreId + }; + + if (x.StoreId == 0) + { + settingModel.Store = allStoresString; + } + else + { + var store = stores.FirstOrDefault(s => s.Id == x.StoreId); + settingModel.Store = store != null ? store.Name : "".NaIfEmpty(); + } + + return settingModel; + }) + .ForCommand(command) + .ToList(); + + model.Data = settings.PagedForCommand(command); + model.Total = settings.Count; + } + else + { + model.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } return new JsonResult { @@ -1580,80 +1585,76 @@ public ActionResult AllSettings(GridCommand command) [GridAction(EnableCustomBinding = true)] public ActionResult SettingUpdate(SettingModel model, GridCommand command) { - if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageSettings)) - return AccessDeniedView(); - - if (model.Name != null) - model.Name = model.Name.Trim(); - if (model.Value != null) - model.Value = model.Value.Trim(); + if (_services.Permissions.Authorize(StandardPermissionProvider.ManageSettings)) + { + if (model.Name != null) + model.Name = model.Name.Trim(); + if (model.Value != null) + model.Value = model.Value.Trim(); - if (!ModelState.IsValid) - { - //display the first model error - var modelStateErrors = this.ModelState.Values.SelectMany(x => x.Errors).Select(x => x.ErrorMessage); - return Content(modelStateErrors.FirstOrDefault()); - } + if (!ModelState.IsValid) + { + var modelStateErrors = this.ModelState.Values.SelectMany(x => x.Errors).Select(x => x.ErrorMessage); + return Content(modelStateErrors.FirstOrDefault()); + } - var setting = _services.Settings.GetSettingById(model.Id); - if (setting == null) - return Content(_services.Localization.GetResource("Admin.Configuration.Settings.NoneWithThatId")); + var setting = _services.Settings.GetSettingById(model.Id); + if (setting == null) + return Content(T("Admin.Configuration.Settings.NoneWithThatId")); - var storeId = model.Store.ToInt(); //use Store property (not StoreId) because appropriate property is stored in it + var storeId = model.Store.ToInt(); //use Store property (not StoreId) because appropriate property is stored in it - if (!setting.Name.Equals(model.Name, StringComparison.InvariantCultureIgnoreCase) || - setting.StoreId != storeId) - { - //setting name or store has been changed - _services.Settings.DeleteSetting(setting); - } + if (!setting.Name.Equals(model.Name, StringComparison.InvariantCultureIgnoreCase) || setting.StoreId != storeId) + { + //setting name or store has been changed + _services.Settings.DeleteSetting(setting); + } - _services.Settings.SetSetting(model.Name, model.Value, storeId); + _services.Settings.SetSetting(model.Name, model.Value, storeId); - //activity log - _customerActivityService.InsertActivity("EditSettings", _services.Localization.GetResource("ActivityLog.EditSettings")); + //activity log + _customerActivityService.InsertActivity("EditSettings", T("ActivityLog.EditSettings")); + } return AllSettings(command); } [GridAction(EnableCustomBinding = true)] public ActionResult SettingAdd([Bind(Exclude = "Id")] SettingModel model, GridCommand command) { - if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageSettings)) - return AccessDeniedView(); - - if (model.Name != null) - model.Name = model.Name.Trim(); - if (model.Value != null) - model.Value = model.Value.Trim(); + if (_services.Permissions.Authorize(StandardPermissionProvider.ManageSettings)) + { + if (model.Name != null) + model.Name = model.Name.Trim(); + if (model.Value != null) + model.Value = model.Value.Trim(); - if (!ModelState.IsValid) - { - //display the first model error - var modelStateErrors = this.ModelState.Values.SelectMany(x => x.Errors).Select(x => x.ErrorMessage); - return Content(modelStateErrors.FirstOrDefault()); - } + if (!ModelState.IsValid) + { + var modelStateErrors = this.ModelState.Values.SelectMany(x => x.Errors).Select(x => x.ErrorMessage); + return Content(modelStateErrors.FirstOrDefault()); + } - var storeId = model.Store.ToInt(); //use Store property (not StoreId) because appropriate property is stored in it - _services.Settings.SetSetting(model.Name, model.Value, storeId); + var storeId = model.Store.ToInt(); //use Store property (not StoreId) because appropriate property is stored in it + _services.Settings.SetSetting(model.Name, model.Value, storeId); - //activity log - _customerActivityService.InsertActivity("AddNewSetting", _services.Localization.GetResource("ActivityLog.AddNewSetting"), model.Name); + //activity log + _customerActivityService.InsertActivity("AddNewSetting", T("ActivityLog.AddNewSetting", model.Name)); + } return AllSettings(command); } [GridAction(EnableCustomBinding = true)] public ActionResult SettingDelete(int id, GridCommand command) { - if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageSettings)) - return AccessDeniedView(); + if (_services.Permissions.Authorize(StandardPermissionProvider.ManageSettings)) + { + var setting = _services.Settings.GetSettingById(id); - var setting = _services.Settings.GetSettingById(id); - if (setting == null) - throw new ArgumentException("No setting found with the specified id"); - _services.Settings.DeleteSetting(setting); + _services.Settings.DeleteSetting(setting); - //activity log - _customerActivityService.InsertActivity("DeleteSetting", _services.Localization.GetResource("ActivityLog.DeleteSetting"), setting.Name); + //activity log + _customerActivityService.InsertActivity("DeleteSetting", T("ActivityLog.DeleteSetting", setting.Name)); + } return AllSettings(command); } diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/ShippingController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/ShippingController.cs index a63f02506f..887b5dabbc 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/ShippingController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/ShippingController.cs @@ -149,19 +149,24 @@ public ActionResult Methods() [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult Methods(GridCommand command) { - if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageShippingSettings)) - return AccessDeniedView(); + var model = new GridModel(); - var shippingMethodsModel = _shippingService.GetAllShippingMethods() - .Select(x => x.ToModel()) - .ForCommand(command) - .ToList(); + if (_services.Permissions.Authorize(StandardPermissionProvider.ManageShippingSettings)) + { + var shippingMethodsModel = _shippingService.GetAllShippingMethods() + .Select(x => x.ToModel()) + .ForCommand(command) + .ToList(); - var model = new GridModel - { - Data = shippingMethodsModel, - Total = shippingMethodsModel.Count - }; + model.Data = shippingMethodsModel; + model.Total = shippingMethodsModel.Count; + } + else + { + model.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } return new JsonResult { diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/ShoppingCartController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/ShoppingCartController.cs index b6868c18ce..fccebd040d 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/ShoppingCartController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/ShoppingCartController.cs @@ -65,28 +65,32 @@ public ActionResult CurrentCarts() [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult CurrentCarts(GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageOrders)) - return AccessDeniedView(); - - var customers = _customerService.GetAllCustomers(null, null, null, null, null, - null, null, 0, 0, null, null, null, true, ShoppingCartType.ShoppingCart, - command.Page - 1, command.PageSize); + var gridModel = new GridModel(); + + if (_permissionService.Authorize(StandardPermissionProvider.ManageOrders)) + { + var customers = _customerService.GetAllCustomers(null, null, null, null, null, null, null, + 0, 0, null, null, null, true, ShoppingCartType.ShoppingCart, command.Page - 1, command.PageSize); + + gridModel.Data = customers.Select(x => + { + return new ShoppingCartModel + { + CustomerId = x.Id, + CustomerEmail = x.IsGuest() ? T("Admin.Customers.Guest").Text : x.Email, + TotalItems = x.CountProductsInCart(ShoppingCartType.ShoppingCart) + }; + }); + + gridModel.Total = customers.TotalCount; + } + else + { + gridModel.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } - var gridModel = new GridModel - { - Data = customers.Select(x => - { - return new ShoppingCartModel() - { - CustomerId = x.Id, - CustomerEmail = x.IsGuest() ? - _localizationService.GetResource("Admin.Customers.Guest") : - x.Email, - TotalItems = x.CountProductsInCart(ShoppingCartType.ShoppingCart) - }; - }), - Total = customers.TotalCount - }; return new JsonResult { Data = gridModel @@ -96,35 +100,43 @@ public ActionResult CurrentCarts(GridCommand command) [GridAction(EnableCustomBinding = true)] public ActionResult GetCartDetails(int customerId) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageOrders)) - return AccessDeniedView(); + var gridModel = new GridModel(); - var customer = _customerService.GetCustomerById(customerId); - var cart = customer.GetCartItems(ShoppingCartType.ShoppingCart); + if (_permissionService.Authorize(StandardPermissionProvider.ManageOrders)) + { + var customer = _customerService.GetCustomerById(customerId); + var cart = customer.GetCartItems(ShoppingCartType.ShoppingCart); - var gridModel = new GridModel() - { - Data = cart.Select(sci => - { - decimal taxRate; + gridModel.Data = cart.Select(sci => + { + decimal taxRate; var store = _storeService.GetStoreById(sci.Item.StoreId); - var sciModel = new ShoppingCartItemModel() - { - Id = sci.Item.Id, - Store = store != null ? store.Name : "Unknown", + + var sciModel = new ShoppingCartItemModel + { + Id = sci.Item.Id, + Store = store != null ? store.Name : "".NaIfEmpty(), ProductId = sci.Item.ProductId, - Quantity = sci.Item.Quantity, + Quantity = sci.Item.Quantity, ProductName = sci.Item.Product.Name, ProductTypeName = sci.Item.Product.GetProductTypeLabel(_localizationService), ProductTypeLabelHint = sci.Item.Product.ProductTypeLabelHint, - UnitPrice = _priceFormatter.FormatPrice(_taxService.GetProductPrice(sci.Item.Product, _priceCalculationService.GetUnitPrice(sci, true), out taxRate)), - Total = _priceFormatter.FormatPrice(_taxService.GetProductPrice(sci.Item.Product, _priceCalculationService.GetSubTotal(sci, true), out taxRate)), - UpdatedOn = _dateTimeHelper.ConvertToUserTime(sci.Item.UpdatedOnUtc, DateTimeKind.Utc) - }; - return sciModel; - }), - Total = cart.Count - }; + UnitPrice = _priceFormatter.FormatPrice(_taxService.GetProductPrice(sci.Item.Product, _priceCalculationService.GetUnitPrice(sci, true), out taxRate)), + Total = _priceFormatter.FormatPrice(_taxService.GetProductPrice(sci.Item.Product, _priceCalculationService.GetSubTotal(sci, true), out taxRate)), + UpdatedOn = _dateTimeHelper.ConvertToUserTime(sci.Item.UpdatedOnUtc, DateTimeKind.Utc) + }; + return sciModel; + }); + + gridModel.Total = cart.Count; + } + else + { + gridModel.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } + return new JsonResult { Data = gridModel @@ -144,28 +156,32 @@ public ActionResult CurrentWishlists() [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult CurrentWishlists(GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageOrders)) - return AccessDeniedView(); - - var customers = _customerService.GetAllCustomers(null, null, null, null, null, - null, null, 0, 0, null, null, null, - true, ShoppingCartType.Wishlist, command.Page - 1, command.PageSize); + var gridModel = new GridModel(); + + if (_permissionService.Authorize(StandardPermissionProvider.ManageOrders)) + { + var customers = _customerService.GetAllCustomers(null, null, null, null, null, null, null, + 0, 0, null, null, null, true, ShoppingCartType.Wishlist, command.Page - 1, command.PageSize); + + gridModel.Data = customers.Select(x => + { + return new ShoppingCartModel + { + CustomerId = x.Id, + CustomerEmail = x.IsGuest() ? T("Admin.Customers.Guest").Text : x.Email, + TotalItems = x.CountProductsInCart(ShoppingCartType.Wishlist) + }; + }); + + gridModel.Total = customers.TotalCount; + } + else + { + gridModel.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } - var gridModel = new GridModel - { - Data = customers.Select(x => - { - return new ShoppingCartModel() - { - CustomerId = x.Id, - CustomerEmail = x.IsGuest() ? - _localizationService.GetResource("Admin.Customers.Guest") : - x.Email, - TotalItems = x.CountProductsInCart(ShoppingCartType.Wishlist) - }; - }), - Total = customers.TotalCount - }; return new JsonResult { Data = gridModel @@ -175,35 +191,43 @@ public ActionResult CurrentWishlists(GridCommand command) [GridAction(EnableCustomBinding = true)] public ActionResult GetWishlistDetails(int customerId) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageOrders)) - return AccessDeniedView(); + var gridModel = new GridModel(); - var customer = _customerService.GetCustomerById(customerId); - var cart = customer.GetCartItems(ShoppingCartType.Wishlist); + if (_permissionService.Authorize(StandardPermissionProvider.ManageOrders)) + { + var customer = _customerService.GetCustomerById(customerId); + var cart = customer.GetCartItems(ShoppingCartType.Wishlist); - var gridModel = new GridModel() - { - Data = cart.Select(sci => - { - decimal taxRate; - var store = _storeService.GetStoreById(sci.Item.StoreId); - var sciModel = new ShoppingCartItemModel() - { - Id = sci.Item.Id, - Store = store != null ? store.Name : "Unknown", - ProductId = sci.Item.ProductId, - Quantity = sci.Item.Quantity, + gridModel.Data = cart.Select(sci => + { + decimal taxRate; + var store = _storeService.GetStoreById(sci.Item.StoreId); + + var sciModel = new ShoppingCartItemModel + { + Id = sci.Item.Id, + Store = store != null ? store.Name : "".NaIfEmpty(), + ProductId = sci.Item.ProductId, + Quantity = sci.Item.Quantity, ProductName = sci.Item.Product.Name, ProductTypeName = sci.Item.Product.GetProductTypeLabel(_localizationService), ProductTypeLabelHint = sci.Item.Product.ProductTypeLabelHint, - UnitPrice = _priceFormatter.FormatPrice(_taxService.GetProductPrice(sci.Item.Product, _priceCalculationService.GetUnitPrice(sci, true), out taxRate)), - Total = _priceFormatter.FormatPrice(_taxService.GetProductPrice(sci.Item.Product, _priceCalculationService.GetSubTotal(sci, true), out taxRate)), - UpdatedOn = _dateTimeHelper.ConvertToUserTime(sci.Item.UpdatedOnUtc, DateTimeKind.Utc) - }; - return sciModel; - }), - Total = cart.Count - }; + UnitPrice = _priceFormatter.FormatPrice(_taxService.GetProductPrice(sci.Item.Product, _priceCalculationService.GetUnitPrice(sci, true), out taxRate)), + Total = _priceFormatter.FormatPrice(_taxService.GetProductPrice(sci.Item.Product, _priceCalculationService.GetSubTotal(sci, true), out taxRate)), + UpdatedOn = _dateTimeHelper.ConvertToUserTime(sci.Item.UpdatedOnUtc, DateTimeKind.Utc) + }; + return sciModel; + }); + + gridModel.Total = cart.Count; + } + else + { + gridModel.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } + return new JsonResult { Data = gridModel diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/SpecificationAttributeController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/SpecificationAttributeController.cs index 92877bbb9b..a15ca73afc 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/SpecificationAttributeController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/SpecificationAttributeController.cs @@ -121,28 +121,31 @@ public ActionResult List() [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult List(GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); - - var optionsText = _localizationService.GetResource("Admin.Catalog.Attributes.SpecificationAttributes.Options"); - - var data = _specificationAttributeService.GetSpecificationAttributes() - .Expand(x => x.SpecificationAttributeOptions) - .ForCommand(command) - .Select(x => - { - var model = x.ToModel(); - model.OptionCount = x.SpecificationAttributeOptions.Count; - - return model; - }) - .ToList(); + var gridModel = new GridModel(); - var gridModel = new GridModel + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + var data = _specificationAttributeService.GetSpecificationAttributes() + .Expand(x => x.SpecificationAttributeOptions) + .ForCommand(command) + .Select(x => + { + var model = x.ToModel(); + model.OptionCount = x.SpecificationAttributeOptions.Count; + + return model; + }) + .ToList(); + + gridModel.Data = data.PagedForCommand(command); + gridModel.Total = data.Count; + } + else { - Data = data.PagedForCommand(command), - Total = data.Count - }; + gridModel.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } return new JsonResult { @@ -150,7 +153,6 @@ public ActionResult List(GridCommand command) }; } - //create public ActionResult Create() { if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) @@ -185,7 +187,6 @@ public ActionResult Create(SpecificationAttributeModel model, bool continueEditi return View(model); } - //edit public ActionResult Edit(int id) { if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) @@ -233,7 +234,6 @@ public ActionResult Edit(SpecificationAttributeModel model, bool continueEditing return View(model); } - //delete [HttpPost, ActionName("Delete")] public ActionResult DeleteConfirmed(int id) { @@ -289,35 +289,31 @@ public ActionResult ProductMappingEdit(int specificationAttributeId, string fiel #region Specification attribute options - //list [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult OptionList(int specificationAttributeId, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); + var gridModel = new GridModel(); + + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + var options = _specificationAttributeService.GetSpecificationAttributeOptionsBySpecificationAttribute(specificationAttributeId); + + gridModel.Data = options.Select(x => x.ToModel()); + gridModel.Total = options.Count(); + } + else + { + gridModel.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } - var options = _specificationAttributeService.GetSpecificationAttributeOptionsBySpecificationAttribute(specificationAttributeId); - var gridModel = new GridModel - { - Data = options.Select(x => - { - var model = x.ToModel(); - //locales - //AddLocales(_languageService, model.Locales, (locale, languageId) => - //{ - // locale.Name = x.GetLocalized(y => y.Name, languageId, false, false); - //}); - return model; - }), - Total = options.Count() - }; return new JsonResult { Data = gridModel }; } - //create public ActionResult OptionCreatePopup(int specificationAttributeId) { if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) @@ -367,7 +363,6 @@ public ActionResult OptionCreatePopup(string btnId, string formId, Specification return View(model); } - //edit public ActionResult OptionEditPopup(int id) { if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) @@ -414,23 +409,19 @@ public ActionResult OptionEditPopup(string btnId, string formId, SpecificationAt return View(model); } - //delete [GridAction(EnableCustomBinding = true)] public ActionResult OptionDelete(int optionId, int specificationAttributeId, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) - return AccessDeniedView(); - - var sao = _specificationAttributeService.GetSpecificationAttributeOptionById(optionId); - if (sao == null) - throw new ArgumentException("No specification attribute option found with the specified id"); + if (_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) + { + var sao = _specificationAttributeService.GetSpecificationAttributeOptionById(optionId); - _specificationAttributeService.DeleteSpecificationAttributeOption(sao); + _specificationAttributeService.DeleteSpecificationAttributeOption(sao); + } return OptionList(specificationAttributeId, command); } - //ajax [AcceptVerbs(HttpVerbs.Get)] public ActionResult GetOptionsByAttributeId(string attributeId) @@ -468,7 +459,6 @@ public ActionResult SetAttributeValue(string pk, string value, string name, Form } } - #endregion } } diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/StoreController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/StoreController.cs index 78a441460e..38df324a4c 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/StoreController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/StoreController.cs @@ -81,27 +81,32 @@ from m in stores [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult List(GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageStores)) - return AccessDeniedView(); + var gridModel = new GridModel(); - var storeModels = _storeService.GetAllStores() - .Select(x => - { - var model = x.ToModel(); + if (_permissionService.Authorize(StandardPermissionProvider.ManageStores)) + { + var storeModels = _storeService.GetAllStores() + .Select(x => + { + var model = x.ToModel(); - PrepareStoreModel(model, x); + PrepareStoreModel(model, x); - model.Hosts = model.Hosts.EmptyNull().Replace(",", "
"); + model.Hosts = model.Hosts.EmptyNull().Replace(",", "
"); - return model; - }) - .ToList(); + return model; + }) + .ToList(); - var gridModel = new GridModel + gridModel.Data = storeModels; + gridModel.Total = storeModels.Count(); + } + else { - Data = storeModels, - Total = storeModels.Count() - }; + gridModel.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } return new JsonResult { diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/TaxController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/TaxController.cs index b78404407d..a694f7df48 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/TaxController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/TaxController.cs @@ -116,18 +116,24 @@ public ActionResult Categories() [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult Categories(GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageTaxSettings)) - return AccessDeniedView(); + var model = new GridModel(); - var categoriesModel = _taxCategoryService.GetAllTaxCategories() - .Select(x => x.ToModel()) - .ForCommand(command) - .ToList(); - var model = new GridModel - { - Data = categoriesModel, - Total = categoriesModel.Count - }; + if (_permissionService.Authorize(StandardPermissionProvider.ManageTaxSettings)) + { + var categoriesModel = _taxCategoryService.GetAllTaxCategories() + .Select(x => x.ToModel()) + .ForCommand(command) + .ToList(); + + model.Data = categoriesModel; + model.Total = categoriesModel.Count; + } + else + { + model.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } return new JsonResult { @@ -138,19 +144,19 @@ public ActionResult Categories(GridCommand command) [GridAction(EnableCustomBinding = true)] public ActionResult CategoryUpdate(TaxCategoryModel model, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageTaxSettings)) - return AccessDeniedView(); + if (_permissionService.Authorize(StandardPermissionProvider.ManageTaxSettings)) + { + if (!ModelState.IsValid) + { + var modelStateErrors = this.ModelState.Values.SelectMany(x => x.Errors).Select(x => x.ErrorMessage); + return Content(modelStateErrors.FirstOrDefault()); + } - if (!ModelState.IsValid) - { - //display the first model error - var modelStateErrors = this.ModelState.Values.SelectMany(x => x.Errors).Select(x => x.ErrorMessage); - return Content(modelStateErrors.FirstOrDefault()); - } + var taxCategory = _taxCategoryService.GetTaxCategoryById(model.Id); + taxCategory = model.ToEntity(taxCategory); - var taxCategory = _taxCategoryService.GetTaxCategoryById(model.Id); - taxCategory = model.ToEntity(taxCategory); - _taxCategoryService.UpdateTaxCategory(taxCategory); + _taxCategoryService.UpdateTaxCategory(taxCategory); + } return Categories(command); } @@ -158,19 +164,19 @@ public ActionResult CategoryUpdate(TaxCategoryModel model, GridCommand command) [GridAction(EnableCustomBinding = true)] public ActionResult CategoryAdd([Bind(Exclude = "Id")] TaxCategoryModel model, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageTaxSettings)) - return AccessDeniedView(); + if (_permissionService.Authorize(StandardPermissionProvider.ManageTaxSettings)) + { + if (!ModelState.IsValid) + { + var modelStateErrors = this.ModelState.Values.SelectMany(x => x.Errors).Select(x => x.ErrorMessage); + return Content(modelStateErrors.FirstOrDefault()); + } - if (!ModelState.IsValid) - { - //display the first model error - var modelStateErrors = this.ModelState.Values.SelectMany(x => x.Errors).Select(x => x.ErrorMessage); - return Content(modelStateErrors.FirstOrDefault()); - } + var taxCategory = new TaxCategory(); + taxCategory = model.ToEntity(taxCategory); - var taxCategory = new TaxCategory(); - taxCategory = model.ToEntity(taxCategory); - _taxCategoryService.InsertTaxCategory(taxCategory); + _taxCategoryService.InsertTaxCategory(taxCategory); + } return Categories(command); } @@ -178,13 +184,12 @@ public ActionResult CategoryAdd([Bind(Exclude = "Id")] TaxCategoryModel model, G [GridAction(EnableCustomBinding = true)] public ActionResult CategoryDelete(int id, GridCommand command) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageTaxSettings)) - return AccessDeniedView(); + if (_permissionService.Authorize(StandardPermissionProvider.ManageTaxSettings)) + { + var taxCategory = _taxCategoryService.GetTaxCategoryById(id); - var taxCategory = _taxCategoryService.GetTaxCategoryById(id); - if (taxCategory == null) - throw new ArgumentException("No tax category found with the specified id"); - _taxCategoryService.DeleteTaxCategory(taxCategory); + _taxCategoryService.DeleteTaxCategory(taxCategory); + } return Categories(command); } diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/TopicController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/TopicController.cs index 29f29762c6..03b4a60c62 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/TopicController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/TopicController.cs @@ -137,20 +137,29 @@ public ActionResult List() [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult List(GridCommand command, TopicListModel model) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageTopics)) - return AccessDeniedView(); + var gridModel = new GridModel(); - var topics = _topicService.GetAllTopics(model.SearchStoreId); - var gridModel = new GridModel - { - Data = topics.Select(x => { + if (_permissionService.Authorize(StandardPermissionProvider.ManageTopics)) + { + var topics = _topicService.GetAllTopics(model.SearchStoreId); + + gridModel.Data = topics.Select(x => + { var item = x.ToModel(); // otherwise maxJsonLength could be exceeded item.Body = ""; return item; - }), - Total = topics.Count - }; + }); + + gridModel.Total = topics.Count; + } + else + { + gridModel.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } + return new JsonResult { MaxJsonLength = int.MaxValue, diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/UrlRecordController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/UrlRecordController.cs index c088c0805d..d51b32bb19 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/UrlRecordController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/UrlRecordController.cs @@ -107,20 +107,19 @@ public ActionResult List(string entityName, int? entityId) [HttpPost, GridAction(EnableCustomBinding = true)] public ActionResult List(GridCommand command, UrlRecordListModel model) { - if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageUrlRecords)) - return AccessDeniedView(); + var gridModel = new GridModel(); - var allLanguages = _languageService.GetAllLanguages(true); - var defaultLanguageName = T("Admin.System.SeNames.Language.Standard"); + if (_services.Permissions.Authorize(StandardPermissionProvider.ManageUrlRecords)) + { + var allLanguages = _languageService.GetAllLanguages(true); + var defaultLanguageName = T("Admin.System.SeNames.Language.Standard"); - var urlRecords = _urlRecordService.GetAllUrlRecords(command.Page - 1, command.PageSize, - model.SeName, model.EntityName, model.EntityId, model.LanguageId, model.IsActive); + var urlRecords = _urlRecordService.GetAllUrlRecords(command.Page - 1, command.PageSize, + model.SeName, model.EntityName, model.EntityId, model.LanguageId, model.IsActive); - var slugsPerEntity = _urlRecordService.CountSlugsPerEntity(urlRecords.Select(x => x.Id).Distinct().ToArray()); + var slugsPerEntity = _urlRecordService.CountSlugsPerEntity(urlRecords.Select(x => x.Id).Distinct().ToArray()); - var gridModel = new GridModel - { - Data = urlRecords.Select(x => + gridModel.Data = urlRecords.Select(x => { string languageName; @@ -141,9 +140,16 @@ public ActionResult List(GridCommand command, UrlRecordListModel model) urlRecordModel.SlugsPerEntity = (slugsPerEntity.ContainsKey(x.Id) ? slugsPerEntity[x.Id] : 0); return urlRecordModel; - }), - Total = urlRecords.TotalCount - }; + }); + + gridModel.Total = urlRecords.TotalCount; + } + else + { + gridModel.Data = Enumerable.Empty(); + + NotifyAccessDenied(); + } return new JsonResult { From 1fa83bdc2017f11dd20ee50efd901e4336aceabe Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Wed, 6 Jan 2016 12:57:00 +0100 Subject: [PATCH 135/626] Localized some hard-coded strings --- .../201512151526290_ImportFramework.cs | 9 +++++++ .../Controllers/ByTotalController.cs | 6 +++-- .../Controllers/FixedRateController.cs | 2 +- .../Providers/ByTotalProvider.cs | 27 ++++++++++--------- .../Providers/FixedRateProvider.cs | 25 +++++++++-------- .../ByWeightShippingComputationMethod.cs | 23 ++++++++++------ .../Controllers/ShippingByWeightController.cs | 6 +++-- .../Controllers/TaxByRegionController.cs | 4 +-- 8 files changed, 64 insertions(+), 38 deletions(-) diff --git a/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs b/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs index 7de4cc953b..35b6497ae1 100644 --- a/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs +++ b/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs @@ -76,6 +76,7 @@ public void MigrateLocaleResources(LocaleResourcesBuilder builder) "Legt die Anzahl der zu berspringenden Datenstze fest."); builder.AddOrUpdate("Common.Unknown", "Unknown", "Unbekannt"); + builder.AddOrUpdate("Common.Unavailable", "Unavailable", "Nicht verfgbar"); builder.AddOrUpdate("Common.Language", "Language", "Sprache"); builder.AddOrUpdate("Admin.Common.ImportFile", "Import file", "Importdatei"); builder.AddOrUpdate("Admin.Common.ImportFiles", "Import files", "Importdateien"); @@ -303,6 +304,14 @@ public void MigrateLocaleResources(LocaleResourcesBuilder builder) builder.AddOrUpdate("Admin.Configuration.Countries.States.CantDeleteWithAddresses", "The state\\province cannot be deleted because it has associated addresses.", "Das Bundesland\\Region kann nicht gelscht werden, weil ihm Adressen zugeordnet sind."); + + builder.AddOrUpdate("Admin.Configuration.Shipping.Methods.NoMethodsLoaded", + "No shipping methods could be loaded.", + "Es konnten keine Versandarten geladen werden."); + + builder.AddOrUpdate("Admin.System.Warnings.NoShipmentItems", + "No shipment items", + "Keine Versand-Artikel"); } } } diff --git a/src/Plugins/SmartStore.Shipping/Controllers/ByTotalController.cs b/src/Plugins/SmartStore.Shipping/Controllers/ByTotalController.cs index 1bf1f643b1..5c5e03f8ab 100644 --- a/src/Plugins/SmartStore.Shipping/Controllers/ByTotalController.cs +++ b/src/Plugins/SmartStore.Shipping/Controllers/ByTotalController.cs @@ -43,7 +43,7 @@ public ActionResult Configure() var shippingMethods = _shippingService.GetAllShippingMethods(); if (shippingMethods.Count == 0) { - return Content("No shipping methods can be loaded"); + return Content(T("Admin.Configuration.Shipping.Methods.NoMethodsLoaded")); } var model = new ByTotalListModel(); @@ -100,10 +100,11 @@ public ActionResult RateUpdate(ByTotalModel model, GridCommand command) { if (!ModelState.IsValid) { - return new JsonResult { Data = "error" }; + return new JsonResult { Data = T("Admin.Common.UnknownError").Text }; } var shippingByTotalRecord = _shippingByTotalService.GetShippingByTotalRecordById(model.Id); + shippingByTotalRecord.Zip = model.Zip == "*" ? null : model.Zip; shippingByTotalRecord.From = model.From; shippingByTotalRecord.To = model.To; @@ -112,6 +113,7 @@ public ActionResult RateUpdate(ByTotalModel model, GridCommand command) shippingByTotalRecord.ShippingChargePercentage = model.ShippingChargePercentage; shippingByTotalRecord.BaseCharge = model.BaseCharge; shippingByTotalRecord.MaxCharge = model.MaxCharge; + _shippingByTotalService.UpdateShippingByTotalRecord(shippingByTotalRecord); return RatesList(command); diff --git a/src/Plugins/SmartStore.Shipping/Controllers/FixedRateController.cs b/src/Plugins/SmartStore.Shipping/Controllers/FixedRateController.cs index f0e510f3b7..353bafe59d 100644 --- a/src/Plugins/SmartStore.Shipping/Controllers/FixedRateController.cs +++ b/src/Plugins/SmartStore.Shipping/Controllers/FixedRateController.cs @@ -29,7 +29,7 @@ public ActionResult Configure() { var shippingMethods = _shippingService.GetAllShippingMethods(); if (shippingMethods.Count == 0) - return Content("No shipping methods can be loaded"); + return Content(T("Admin.Configuration.Shipping.Methods.NoMethodsLoaded")); var tmp = new List(); foreach (var shippingMethod in shippingMethods) diff --git a/src/Plugins/SmartStore.Shipping/Providers/ByTotalProvider.cs b/src/Plugins/SmartStore.Shipping/Providers/ByTotalProvider.cs index 882a576f15..82ec989cf4 100644 --- a/src/Plugins/SmartStore.Shipping/Providers/ByTotalProvider.cs +++ b/src/Plugins/SmartStore.Shipping/Providers/ByTotalProvider.cs @@ -1,20 +1,20 @@ using System; -using System.Data.Entity.Migrations; using System.Web.Routing; using SmartStore.Core; using SmartStore.Core.Domain.Shipping; +using SmartStore.Core.Localization; +using SmartStore.Core.Logging; using SmartStore.Core.Plugins; -using SmartStore.Shipping.Services; using SmartStore.Services.Catalog; using SmartStore.Services.Configuration; using SmartStore.Services.Localization; -using SmartStore.Core.Logging; using SmartStore.Services.Shipping; using SmartStore.Services.Shipping.Tracking; +using SmartStore.Shipping.Services; namespace SmartStore.Shipping { - [SystemName("Shipping.ByTotal")] + [SystemName("Shipping.ByTotal")] [FriendlyName("Shipping by total")] [DisplayOrder(1)] public class ByTotalProvider : IShippingRateComputationMethod, IConfigurable @@ -28,7 +28,6 @@ public class ByTotalProvider : IShippingRateComputationMethod, IConfigurable private readonly ISettingService _settingService; private readonly ILocalizationService _localizationService; - /// /// Ctor /// @@ -56,14 +55,18 @@ public ByTotalProvider(IShippingService shippingService, this._logger = logger; this._settingService = settingService; this._localizationService = localizationService; - } - #region Properties + T = NullLocalizer.Instance; + } - /// - /// Gets a shipping rate computation method type - /// - public ShippingRateComputationMethodType ShippingRateComputationMethodType + #region Properties + + public Localizer T { get; set; } + + /// + /// Gets a shipping rate computation method type + /// + public ShippingRateComputationMethodType ShippingRateComputationMethodType { get { @@ -158,7 +161,7 @@ public GetShippingOptionResponse GetShippingOptions(GetShippingOptionRequest get if (getShippingOptionRequest.Items == null || getShippingOptionRequest.Items.Count == 0) { - response.AddError("No shipment items"); + response.AddError(T("Admin.System.Warnings.NoShipmentItems")); return response; } diff --git a/src/Plugins/SmartStore.Shipping/Providers/FixedRateProvider.cs b/src/Plugins/SmartStore.Shipping/Providers/FixedRateProvider.cs index a4ae31c94e..cc303cee6e 100644 --- a/src/Plugins/SmartStore.Shipping/Providers/FixedRateProvider.cs +++ b/src/Plugins/SmartStore.Shipping/Providers/FixedRateProvider.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Web.Routing; using SmartStore.Core.Domain.Shipping; +using SmartStore.Core.Localization; using SmartStore.Core.Plugins; using SmartStore.Services.Configuration; using SmartStore.Services.Localization; @@ -10,27 +11,29 @@ namespace SmartStore.Shipping { - /// - /// Fixed rate shipping computation provider - /// - [SystemName("Shipping.FixedRate")] + /// + /// Fixed rate shipping computation provider + /// + [SystemName("Shipping.FixedRate")] [FriendlyName("Fixed Rate Shipping")] [DisplayOrder(0)] public class FixedRateProvider : IShippingRateComputationMethod, IConfigurable { private readonly ISettingService _settingService; private readonly IShippingService _shippingService; - private readonly ILocalizationService _localizationService; public FixedRateProvider(ISettingService settingService, - IShippingService shippingService, ILocalizationService localizationService) + IShippingService shippingService) { this._settingService = settingService; this._shippingService = shippingService; - _localizationService = localizationService; - } - - private decimal GetRate(int shippingMethodId) + + T = NullLocalizer.Instance; + } + + public Localizer T { get; set; } + + private decimal GetRate(int shippingMethodId) { string key = string.Format("ShippingRateComputationMethod.FixedRate.Rate.ShippingMethodId{0}", shippingMethodId); decimal rate = this._settingService.GetSettingByKey(key); @@ -51,7 +54,7 @@ public GetShippingOptionResponse GetShippingOptions(GetShippingOptionRequest get if (getShippingOptionRequest.Items == null || getShippingOptionRequest.Items.Count == 0) { - response.AddError("No shipment items"); + response.AddError(T("Admin.System.Warnings.NoShipmentItems")); return response; } diff --git a/src/Plugins/SmartStore.ShippingByWeight/ByWeightShippingComputationMethod.cs b/src/Plugins/SmartStore.ShippingByWeight/ByWeightShippingComputationMethod.cs index 0c59828d2a..40334476a9 100644 --- a/src/Plugins/SmartStore.ShippingByWeight/ByWeightShippingComputationMethod.cs +++ b/src/Plugins/SmartStore.ShippingByWeight/ByWeightShippingComputationMethod.cs @@ -3,15 +3,16 @@ using System.Web.Routing; using SmartStore.Core; using SmartStore.Core.Domain.Shipping; +using SmartStore.Core.Localization; using SmartStore.Core.Plugins; -using SmartStore.ShippingByWeight.Data; -using SmartStore.ShippingByWeight.Data.Migrations; -using SmartStore.ShippingByWeight.Services; using SmartStore.Services; using SmartStore.Services.Catalog; using SmartStore.Services.Localization; using SmartStore.Services.Shipping; using SmartStore.Services.Shipping.Tracking; +using SmartStore.ShippingByWeight.Data; +using SmartStore.ShippingByWeight.Data.Migrations; +using SmartStore.ShippingByWeight.Services; namespace SmartStore.ShippingByWeight { @@ -32,6 +33,7 @@ public class ByWeightShippingComputationMethod : BasePlugin, IShippingRateComput #endregion #region Ctor + public ByWeightShippingComputationMethod(IShippingService shippingService, IStoreContext storeContext, IShippingByWeightService shippingByWeightService, @@ -51,12 +53,17 @@ public ByWeightShippingComputationMethod(IShippingService shippingService, this._localizationService = localizationService; this._priceFormatter = priceFormatter; this._services = services; - } - #endregion - #region Utilities + T = NullLocalizer.Instance; + } + + public Localizer T { get; set; } + + #endregion + + #region Utilities - private decimal? GetRate(decimal subTotal, decimal weight, int shippingMethodId, int storeId, int countryId, string zip) + private decimal? GetRate(decimal subTotal, decimal weight, int shippingMethodId, int storeId, int countryId, string zip) { decimal? shippingTotal = null; @@ -120,7 +127,7 @@ public GetShippingOptionResponse GetShippingOptions(GetShippingOptionRequest get if (getShippingOptionRequest.Items == null || getShippingOptionRequest.Items.Count == 0) { - response.AddError("No shipment items"); + response.AddError(T("Admin.System.Warnings.NoShipmentItems")); return response; } diff --git a/src/Plugins/SmartStore.ShippingByWeight/Controllers/ShippingByWeightController.cs b/src/Plugins/SmartStore.ShippingByWeight/Controllers/ShippingByWeightController.cs index aaa92a955f..383d77dfa2 100644 --- a/src/Plugins/SmartStore.ShippingByWeight/Controllers/ShippingByWeightController.cs +++ b/src/Plugins/SmartStore.ShippingByWeight/Controllers/ShippingByWeightController.cs @@ -50,8 +50,10 @@ public ShippingByWeightController( public ActionResult Configure() { var shippingMethods = _shippingService.GetAllShippingMethods(); - if (shippingMethods.Count == 0) - return Content("No shipping methods can be loaded"); + if (shippingMethods.Count == 0) + { + return Content(T("Admin.Configuration.Shipping.Methods.NoMethodsLoaded")); + } var model = new ShippingByWeightListModel(); var countries = _countryService.GetAllCountries(true); diff --git a/src/Plugins/SmartStore.Tax/Controllers/TaxByRegionController.cs b/src/Plugins/SmartStore.Tax/Controllers/TaxByRegionController.cs index 53bc5628e7..ca43d31f14 100644 --- a/src/Plugins/SmartStore.Tax/Controllers/TaxByRegionController.cs +++ b/src/Plugins/SmartStore.Tax/Controllers/TaxByRegionController.cs @@ -70,7 +70,7 @@ public ActionResult Configure() var tc = _taxCategoryService.GetTaxCategoryById(x.TaxCategoryId); m.TaxCategoryName = (tc != null) ? tc.Name : ""; var c = _countryService.GetCountryById(x.CountryId); - m.CountryName = (c != null) ? c.Name : "Unavailable"; + m.CountryName = (c != null) ? c.Name : T("Common.Unavailable").Text; var s = _stateProvinceService.GetStateProvinceById(x.StateProvinceId); m.StateProvinceName = (s != null) ? s.Name : "*"; m.Zip = (!String.IsNullOrEmpty(x.Zip)) ? x.Zip : "*"; @@ -99,7 +99,7 @@ public ActionResult RatesList(GridCommand command) var tc = _taxCategoryService.GetTaxCategoryById(x.TaxCategoryId); m.TaxCategoryName = (tc != null) ? tc.Name : ""; var c = _countryService.GetCountryById(x.CountryId); - m.CountryName = (c != null) ? c.Name : "Unavailable"; + m.CountryName = (c != null) ? c.Name : T("Common.Unavailable").Text; var s = _stateProvinceService.GetStateProvinceById(x.StateProvinceId); m.StateProvinceName = (s != null) ? s.Name : "*"; m.Zip = (!String.IsNullOrEmpty(x.Zip)) ? x.Zip : "*"; From 07432d249b21eb3b5f8e089bb20ef63d322ea786 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Thu, 7 Jan 2016 11:52:49 +0100 Subject: [PATCH 136/626] GMC feed: Supporting fields multipack, bundle, adult, energy efficiency class and custom label (0 to 4) --- changelog.md | 1 + .../201512151526290_ImportFramework.cs | 4 + .../FeedGoogleMerchantCenterController.cs | 31 +++- .../Data/GoogleProductRecordMap.cs | 10 +- .../201601061649324_IsBundle.Designer.cs | 29 ++++ .../Migrations/201601061649324_IsBundle.cs | 34 ++++ .../Migrations/201601061649324_IsBundle.resx | 126 +++++++++++++++ .../Description.txt | 2 +- .../Domain/GoogleProductRecord.cs | 13 +- .../SmartStore.GoogleMerchantCenter/Events.cs | 39 ++--- .../Extensions/MiscExtensions.cs | 13 +- .../Localization/resources.de-de.xml | 84 +++++++--- .../Localization/resources.en-us.xml | 84 +++++++--- .../Models/FeedGoogleMerchantCenterModel.cs | 53 +++++-- .../Models/ProfileConfigurationModel.cs | 4 - .../Providers/GmcXmlExportProvider.cs | 59 ++++++- .../Services/GoogleFeedService.cs | 54 ++++++- .../SmartStore.GoogleMerchantCenter.csproj | 7 + .../FeedGoogleMerchantCenter/Configure.cshtml | 146 ++++++++++++++---- .../ProductEditTab.cshtml | 97 +++++++++++- .../ProfileConfiguration.cshtml | 15 +- .../changelog.md | 7 + 22 files changed, 748 insertions(+), 164 deletions(-) create mode 100644 src/Plugins/SmartStore.GoogleMerchantCenter/Data/Migrations/201601061649324_IsBundle.Designer.cs create mode 100644 src/Plugins/SmartStore.GoogleMerchantCenter/Data/Migrations/201601061649324_IsBundle.cs create mode 100644 src/Plugins/SmartStore.GoogleMerchantCenter/Data/Migrations/201601061649324_IsBundle.resx diff --git a/changelog.md b/changelog.md index 2308726b85..f6fa16e556 100644 --- a/changelog.md +++ b/changelog.md @@ -32,6 +32,7 @@ * #840 Activity log: Have option to exclude search engine activity * #841 Activity log for deleting an order * More settings to control creation of SEO names +* GMC feed: Supporting fields multipack, bundle, adult, energy efficiency class and custom label (0 to 4) ### Improvements * (Perf) Implemented static caches for URL aliases and localized properties. Increases app startup and request speed by up to 30%. diff --git a/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs b/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs index 35b6497ae1..7f2dec3086 100644 --- a/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs +++ b/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs @@ -312,6 +312,10 @@ public void MigrateLocaleResources(LocaleResourcesBuilder builder) builder.AddOrUpdate("Admin.System.Warnings.NoShipmentItems", "No shipment items", "Keine Versand-Artikel"); + + builder.AddOrUpdate("Admin.System.Warnings.DigitsOnly", + "Please enter digits only.", + "Bitte nur Ziffern eingeben."); } } } diff --git a/src/Plugins/SmartStore.GoogleMerchantCenter/Controllers/FeedGoogleMerchantCenterController.cs b/src/Plugins/SmartStore.GoogleMerchantCenter/Controllers/FeedGoogleMerchantCenterController.cs index 74b368fe98..6c37461c87 100644 --- a/src/Plugins/SmartStore.GoogleMerchantCenter/Controllers/FeedGoogleMerchantCenterController.cs +++ b/src/Plugins/SmartStore.GoogleMerchantCenter/Controllers/FeedGoogleMerchantCenterController.cs @@ -36,21 +36,31 @@ public ActionResult ProductEditTab(int productId) var culture = CultureInfo.InvariantCulture; var model = new GoogleProductModel { ProductId = productId }; var entity = _googleFeedService.GetGoogleProductRecord(productId); + string notSpecified = T("Common.Unspecified"); if (entity != null) { model.Taxonomy = entity.Taxonomy; model.Gender = entity.Gender; model.AgeGroup = entity.AgeGroup; + model.IsAdult = entity.IsAdult; model.Color = entity.Color; model.Size = entity.Size; model.Material = entity.Material; model.Pattern = entity.Pattern; - model.Exporting = entity.Export; + model.Export2 = entity.Export; + model.Multipack2 = entity.Multipack; + model.IsBundle = entity.IsBundle; + model.EnergyEfficiencyClass = entity.EnergyEfficiencyClass; + model.CustomLabel0 = entity.CustomLabel0; + model.CustomLabel1 = entity.CustomLabel1; + model.CustomLabel2 = entity.CustomLabel2; + model.CustomLabel3 = entity.CustomLabel3; + model.CustomLabel4 = entity.CustomLabel4; } else { - model.Exporting = true; + model.Export2 = true; } ViewBag.DefaultCategory = ""; @@ -58,8 +68,13 @@ public ActionResult ProductEditTab(int productId) ViewBag.DefaultSize = ""; ViewBag.DefaultMaterial = ""; ViewBag.DefaultPattern = ""; - ViewBag.DefaultGender = T("Common.Auto"); - ViewBag.DefaultAgeGroup = T("Common.Auto"); + ViewBag.DefaultGender = notSpecified; + ViewBag.DefaultAgeGroup = notSpecified; + ViewBag.DefaultIsAdult = ""; + ViewBag.DefaultMultipack2 = ""; + ViewBag.DefaultIsBundle = ""; + ViewBag.DefaultEnergyEfficiencyClass = notSpecified; + ViewBag.DefaultCustomLabel = ""; // we do not have export profile context here, so we simply use the first profile var profile = _exportService.GetExportProfilesBySystemName(GmcXmlExportProvider.SystemName).FirstOrDefault(); @@ -99,6 +114,11 @@ public ActionResult ProductEditTab(int productId) new SelectListItem { Value = "kids", Text = T("Plugins.Feed.Froogle.AgeGroupKids") }, }; + ViewBag.AvailableEnergyEfficiencyClasses = T("Plugins.Feed.Froogle.EnergyEfficiencyClasses").Text + .SplitSafe(",") + .Select(x => new SelectListItem { Value = x, Text = x }) + .ToList(); + var result = PartialView(model); result.ViewData.TemplateInfo = new TemplateInfo { HtmlFieldPrefix = "CustomProperties[GMC]" }; return result; @@ -114,8 +134,9 @@ public ActionResult Configure() { var model = new FeedGoogleMerchantCenterModel(); - model.AvailableGoogleCategories = _googleFeedService.GetTaxonomyList(); model.GridPageSize = _adminAreaSettings.GridPageSize; + model.AvailableGoogleCategories = _googleFeedService.GetTaxonomyList(); + model.EnergyEfficiencyClasses = T("Plugins.Feed.Froogle.EnergyEfficiencyClasses").Text.SplitSafe(","); return View(model); } diff --git a/src/Plugins/SmartStore.GoogleMerchantCenter/Data/GoogleProductRecordMap.cs b/src/Plugins/SmartStore.GoogleMerchantCenter/Data/GoogleProductRecordMap.cs index 5b4e0817ab..98aaec1aa4 100644 --- a/src/Plugins/SmartStore.GoogleMerchantCenter/Data/GoogleProductRecordMap.cs +++ b/src/Plugins/SmartStore.GoogleMerchantCenter/Data/GoogleProductRecordMap.cs @@ -9,6 +9,14 @@ public GoogleProductRecordMap() { this.ToTable("GoogleProduct"); this.HasKey(x => x.Id); - } + + this.Property(x => x.EnergyEfficiencyClass).HasMaxLength(50); + + this.Property(x => x.CustomLabel0).HasMaxLength(100); + this.Property(x => x.CustomLabel1).HasMaxLength(100); + this.Property(x => x.CustomLabel2).HasMaxLength(100); + this.Property(x => x.CustomLabel3).HasMaxLength(100); + this.Property(x => x.CustomLabel4).HasMaxLength(100); + } } } \ No newline at end of file diff --git a/src/Plugins/SmartStore.GoogleMerchantCenter/Data/Migrations/201601061649324_IsBundle.Designer.cs b/src/Plugins/SmartStore.GoogleMerchantCenter/Data/Migrations/201601061649324_IsBundle.Designer.cs new file mode 100644 index 0000000000..652bba012c --- /dev/null +++ b/src/Plugins/SmartStore.GoogleMerchantCenter/Data/Migrations/201601061649324_IsBundle.Designer.cs @@ -0,0 +1,29 @@ +// +namespace SmartStore.GoogleMerchantCenter.Data.Migrations +{ + using System.CodeDom.Compiler; + using System.Data.Entity.Migrations; + using System.Data.Entity.Migrations.Infrastructure; + using System.Resources; + + [GeneratedCode("EntityFramework.Migrations", "6.1.3-40302")] + public sealed partial class IsBundle : IMigrationMetadata + { + private readonly ResourceManager Resources = new ResourceManager(typeof(IsBundle)); + + string IMigrationMetadata.Id + { + get { return "201601061649324_IsBundle"; } + } + + string IMigrationMetadata.Source + { + get { return null; } + } + + string IMigrationMetadata.Target + { + get { return Resources.GetString("Target"); } + } + } +} diff --git a/src/Plugins/SmartStore.GoogleMerchantCenter/Data/Migrations/201601061649324_IsBundle.cs b/src/Plugins/SmartStore.GoogleMerchantCenter/Data/Migrations/201601061649324_IsBundle.cs new file mode 100644 index 0000000000..bc8af7c35e --- /dev/null +++ b/src/Plugins/SmartStore.GoogleMerchantCenter/Data/Migrations/201601061649324_IsBundle.cs @@ -0,0 +1,34 @@ +namespace SmartStore.GoogleMerchantCenter.Data.Migrations +{ + using System; + using System.Data.Entity.Migrations; + + public partial class IsBundle : DbMigration + { + public override void Up() + { + AddColumn("dbo.GoogleProduct", "Multipack", c => c.Int(nullable: false)); + AddColumn("dbo.GoogleProduct", "IsBundle", c => c.Boolean()); + AddColumn("dbo.GoogleProduct", "IsAdult", c => c.Boolean()); + AddColumn("dbo.GoogleProduct", "EnergyEfficiencyClass", c => c.String(maxLength: 50)); + AddColumn("dbo.GoogleProduct", "CustomLabel0", c => c.String(maxLength: 100)); + AddColumn("dbo.GoogleProduct", "CustomLabel1", c => c.String(maxLength: 100)); + AddColumn("dbo.GoogleProduct", "CustomLabel2", c => c.String(maxLength: 100)); + AddColumn("dbo.GoogleProduct", "CustomLabel3", c => c.String(maxLength: 100)); + AddColumn("dbo.GoogleProduct", "CustomLabel4", c => c.String(maxLength: 100)); + } + + public override void Down() + { + DropColumn("dbo.GoogleProduct", "CustomLabel4"); + DropColumn("dbo.GoogleProduct", "CustomLabel3"); + DropColumn("dbo.GoogleProduct", "CustomLabel2"); + DropColumn("dbo.GoogleProduct", "CustomLabel1"); + DropColumn("dbo.GoogleProduct", "CustomLabel0"); + DropColumn("dbo.GoogleProduct", "EnergyEfficiencyClass"); + DropColumn("dbo.GoogleProduct", "IsAdult"); + DropColumn("dbo.GoogleProduct", "IsBundle"); + DropColumn("dbo.GoogleProduct", "Multipack"); + } + } +} diff --git a/src/Plugins/SmartStore.GoogleMerchantCenter/Data/Migrations/201601061649324_IsBundle.resx b/src/Plugins/SmartStore.GoogleMerchantCenter/Data/Migrations/201601061649324_IsBundle.resx new file mode 100644 index 0000000000..ebf95a7c54 --- /dev/null +++ b/src/Plugins/SmartStore.GoogleMerchantCenter/Data/Migrations/201601061649324_IsBundle.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + H4sIAAAAAAAEAM2a227jNhCG7wv0HQRdtUDW8iEF2sDeReIki6BxHETJ3tPS2FGXIlWSCuy+Wi/6SH2Fjs6iJNuSHQe9s0fkNwdS1K+x//37n/GXtU+NNxDS42xiDnp90wDmcNdjq4kZquWnX80vn3/8YXzj+mvjWzZuFI3DmUxOzFelggvLks4r+ET2fM8RXPKl6jnct4jLrWG//5s1GFiACBNZhjF+CpnyfIi/4NcpZw4EKiR0xl2gMrXjFTumGg/EBxkQByam7ROhbMUF9L5yvqIwA+G8EqamwBSI3jVRxDQuqUcwNhvo0jQIY1wRhZFfvEiwleBsZQdoIPR5EwCOWxIqIc3oohjeNrn+MErOKiZmKCeUivsdgYNRWi2rOv2gmpt5NbGeN1h3tYmyjms6MZMaPgruho56AocL1zSqfi+mVERzWlQfp3ms10A9M/bMPcu317A37PV7/TNjGlIVCpgwCJUg9Mx4DBfUc36HzTP/DmzCQkrL6WGCeE0zoAnDCECozRMs06TvMEdLn2dVJ+bTSnOSGtwxNRqaxgM6JwsK+e4p1SvO8iswEESB+0gU5sciBsT1r3mv+EoLt9/lbswzWXPG/U1GwZ2Pt7VpzMj6HthKvU5M/Ggat94a3MySkl+Yh6cATlIi3OsIM3VBnNzN5Qq+Ch4GJ3c05ZSfPh3b+wtO7mSGG1DgQXdyR+kmP7mfOwV+vAuKu+N0vuQzD/GMzT1dcU6BsM534lRAdBDM2YtyMhY+qOAZH4KdYS+B+36wm3XAhTo2vxke1B4+n78fd2DdyauQuRRq4eybduliAB1n3eDpvNrcLJee46Hk2UwpkXLHlvql/x4nS/xkvScLoP0dvgb9d3Y2+Ehnw490NvpIZ+fv7GxsFYKsLtNQFitUUyCatNp88Qc4KhoCa9Ug2VDppqpNpp71JBMXNqjtQhDvhiK8REw3KbvmlPLgCzFvJWo+U/3WFtk/npEgwOqWXgNSi2En7wDTT3Z3KewnDMuRDYo4jzb3hAqOrKByNZIGLtx6QqroPWNBovWdun5t2I6l2rIMmeMdq1EVtsXiZJOjz6m4aPGa1LiYFSdF8W+xHj5OjksDedzNrxA1SvwuRygRDbIa5Vbos23SfNfsklAuQ0rm9qxCLZdRhbU9KZPDZU5ma08p1G6ZU1jbk1I5W8akpvaMRKyWEYmlPaFQomVKYe2w6pnU1NY8M7bnaFJS24TlCx14hVzUaIW5w5ppilFbOu1Ke6IuG8tE/Up7YqYdy6zM1mFfFNpR2xiFucsKZAJSX4DM2oWUakodlBo71KhZZWolax7SYa9oolLbK9qVg4iDrcTBgcThVuLwQOJoK3F0IPF8K/G8iTi2Kg/J6qPaqj2rK+2nqg7YpaiqQ3LvubKqKKhxqmb2d1dr8iYZYhpYqjfPjaSNvZF4PCYCwv6TTiluWlUMmBHmLUGqpENnDvuDYaUd+/9pjVpSurR7f/TDO45eVOC9PcWOL9u1JmPs5cgWI3sjkcwUP/lk/XOZ1r2NeBSq2io8Cqa1A48ilVt+R4Gqbb2jYJXW3VGshvbccbxqC27hdd+lTe23SPKo92q/HQzT22+H5FZrvR1yG1cbb5VA2i2U1oQ7gLCzIZdtolpLruOt3NB/a0TH3ZyD2YMTsocnZI9OyD4/jt2tVVZv03TufrVtfiUKCc+ABccMk/C1gQf3x+qqbWyVfzkfX4P0VgUi+h2dgRPJoQKajbljS54tDuZdjigbUj1ZQBE82MilUN6SOAovOyBl3Pf8RmgY3bL+Atw7Ng9VEKpLKcFfUK1VMrZ2+4+bgHrM43kQfZPvkQKG6UVn85xdhR5187hv64fiNkS0k1LVhVHZKlJfq01OeuCsJSgt3zUEkcxh6hn8gCJMzplN3uCQ2F4k3MOKOJtMfG+H7F8Ivezja4+sBPFlyijmR/8GsaK/g3z+D2Zr4jJAIgAA + + + dbo + + \ No newline at end of file diff --git a/src/Plugins/SmartStore.GoogleMerchantCenter/Description.txt b/src/Plugins/SmartStore.GoogleMerchantCenter/Description.txt index 043c9f3476..55dfd4845a 100644 --- a/src/Plugins/SmartStore.GoogleMerchantCenter/Description.txt +++ b/src/Plugins/SmartStore.GoogleMerchantCenter/Description.txt @@ -1,7 +1,7 @@ FriendlyName: Google Merchant Center (GMC) feed SystemName: SmartStore.GoogleMerchantCenter Group: Marketing -Version: 2.2.0.4 +Version: 2.2.0.5 MinAppVersion: 2.2.0 Author: SmartStore AG DisplayOrder: 1 diff --git a/src/Plugins/SmartStore.GoogleMerchantCenter/Domain/GoogleProductRecord.cs b/src/Plugins/SmartStore.GoogleMerchantCenter/Domain/GoogleProductRecord.cs index cca0f73827..7064e84880 100644 --- a/src/Plugins/SmartStore.GoogleMerchantCenter/Domain/GoogleProductRecord.cs +++ b/src/Plugins/SmartStore.GoogleMerchantCenter/Domain/GoogleProductRecord.cs @@ -29,5 +29,16 @@ public GoogleProductRecord() public DateTime UpdatedOnUtc { get; set; } public bool Export { get; set; } - } + + public int Multipack { get; set; } + public bool? IsBundle { get; set; } + public bool? IsAdult { get; set; } + public string EnergyEfficiencyClass { get; set; } + + public string CustomLabel0 { get; set; } + public string CustomLabel1 { get; set; } + public string CustomLabel2 { get; set; } + public string CustomLabel3 { get; set; } + public string CustomLabel4 { get; set; } + } } \ No newline at end of file diff --git a/src/Plugins/SmartStore.GoogleMerchantCenter/Events.cs b/src/Plugins/SmartStore.GoogleMerchantCenter/Events.cs index 3673c52c20..ea0bd90c3a 100644 --- a/src/Plugins/SmartStore.GoogleMerchantCenter/Events.cs +++ b/src/Plugins/SmartStore.GoogleMerchantCenter/Events.cs @@ -10,8 +10,7 @@ namespace SmartStore.GoogleMerchantCenter { public class Events : IConsumer, - IConsumer/*, - IConsumer*/ + IConsumer { private readonly IGoogleFeedService _googleService; @@ -25,6 +24,7 @@ public void HandleEvent(TabStripCreated eventMessage) if (eventMessage.TabStripName == "product-edit") { var productId = ((TabbableModel)eventMessage.Model).Id; + eventMessage.ItemFactory.Add().Text("GMC") .Name("tab-gmc") .Icon("fa fa-google fa-lg fa-fw") @@ -34,30 +34,6 @@ public void HandleEvent(TabStripCreated eventMessage) } } - //public void HandleEvent(RowExportingEvent eventMessage) - //{ - // if (eventMessage.EntityType != ExportEntityType.Product) - // return; - - // var row = eventMessage.Row; - // var product = eventMessage.Row.Entity as Product; - - // if (product == null) - // return; - - // var gmc = _googleService.GetGoogleProductRecord(product.Id); - // if (gmc == null) - // return; - - // row["_GMC_AgeGroup"] = gmc.AgeGroup; - // row["_GMC_Color"] = gmc.Color; - // row["_GMC_Gender"] = gmc.Gender; - // row["_GMC_Size"] = gmc.Size; - // row["_GMC_Taxonomy"] = gmc.Taxonomy; - // row["_GMC_Material"] = gmc.Material; - // row["_GMC_Pattern"] = gmc.Pattern; - //} - public void HandleEvent(ModelBoundEvent eventMessage) { if (!eventMessage.BoundModel.CustomProperties.ContainsKey("GMC")) @@ -88,8 +64,17 @@ public void HandleEvent(ModelBoundEvent eventMessage) entity.Taxonomy = model.Taxonomy; entity.Material = model.Material; entity.Pattern = model.Pattern; - entity.Export = model.Exporting; + entity.Export = model.Export2; entity.UpdatedOnUtc = utcNow; + entity.Multipack = model.Multipack2 ?? 0; + entity.IsBundle = model.IsBundle; + entity.IsAdult = model.IsAdult; + entity.EnergyEfficiencyClass = model.EnergyEfficiencyClass; + entity.CustomLabel0 = model.CustomLabel0; + entity.CustomLabel1 = model.CustomLabel1; + entity.CustomLabel2 = model.CustomLabel2; + entity.CustomLabel3 = model.CustomLabel3; + entity.CustomLabel4 = model.CustomLabel4; entity.IsTouched = entity.IsTouched(); diff --git a/src/Plugins/SmartStore.GoogleMerchantCenter/Extensions/MiscExtensions.cs b/src/Plugins/SmartStore.GoogleMerchantCenter/Extensions/MiscExtensions.cs index c140111c1e..5a8dd0168d 100644 --- a/src/Plugins/SmartStore.GoogleMerchantCenter/Extensions/MiscExtensions.cs +++ b/src/Plugins/SmartStore.GoogleMerchantCenter/Extensions/MiscExtensions.cs @@ -9,7 +9,7 @@ public static string XEditableLink(this HtmlHelper hlp, string fieldName, string { string displayText = null; - if (fieldName == "Gender" || fieldName == "AgeGroup" || fieldName == "Exporting") + if (fieldName == "Gender" || fieldName == "AgeGroup" || fieldName == "Export2" || fieldName == "IsBundle" || fieldName == "IsAdult") displayText = "<#= {0}Localize #>".FormatInvariant(fieldName); else displayText = "<#= {0} #>".FormatInvariant(fieldName); @@ -22,12 +22,15 @@ public static string XEditableLink(this HtmlHelper hlp, string fieldName, string return skeleton.FormatInvariant(fieldName, fieldName.ToLower(), type, displayText); } - public static bool IsTouched(this GoogleProductRecord product) + public static bool IsTouched(this GoogleProductRecord p) { - if (product != null) + if (p != null) { - return product.Taxonomy.HasValue() || product.Gender.HasValue() || product.AgeGroup.HasValue() || product.Color.HasValue() || - product.Size.HasValue() || product.Material.HasValue() || product.Pattern.HasValue() || product.ItemGroupId.HasValue() || !product.Export; + return + p.Taxonomy.HasValue() || p.Gender.HasValue() || p.AgeGroup.HasValue() || p.Color.HasValue() || + p.Size.HasValue() || p.Material.HasValue() || p.Pattern.HasValue() || p.ItemGroupId.HasValue() || + !p.Export || p.Multipack != 0 || p.IsBundle.HasValue || p.IsAdult.HasValue || p.EnergyEfficiencyClass.HasValue() || + p.CustomLabel0.HasValue() || p.CustomLabel1.HasValue() || p.CustomLabel2.HasValue() || p.CustomLabel3.HasValue() || p.CustomLabel4.HasValue(); } return false; } diff --git a/src/Plugins/SmartStore.GoogleMerchantCenter/Localization/resources.de-de.xml b/src/Plugins/SmartStore.GoogleMerchantCenter/Localization/resources.de-de.xml index e4aa14c576..17b90e856c 100644 --- a/src/Plugins/SmartStore.GoogleMerchantCenter/Localization/resources.de-de.xml +++ b/src/Plugins/SmartStore.GoogleMerchantCenter/Localization/resources.de-de.xml @@ -37,24 +37,9 @@ Google-Kategorie - - Geschlecht - - - Altersgruppe - - - Farbe - - - Größe - - - Material - - - Muster - + + Legt die dem Artikel entsprechende Google-Kategorie fest. Zwingend erforderlich. + Zusätzliche Bilder @@ -148,12 +133,6 @@ Muster oder grafisches Druckdesign eines Produktes. Angabe ist z.B. bei Bekleidung sinnvoll. - - Nur online zu kaufen - - - Legt fest, ob Produkte nur online erworben werden können. Aktivieren Sie diese Option nicht, falls Produkte auch in Ihrem Ladengeschäft erhältlich sind. - Leer @@ -196,4 +175,61 @@ Legt fest, ob der Grundpreis eines Produktes exportiert werden soll. + + Multipack + + + Anzahl identischer Produkte in einem händlerdefinierten Multipack. Muss größer 1 sein. + + + Bundle + + + Händlerdefiniertes Produktpaket bestehend aus einem Haupt- und mehreren Zubehörartikel bzw. Add-ons. + + + Nicht jugendfrei + + + Produkt, welches nur für erwachsene Nutzer bestimmt ist. + + + Energieeffizienz + + + Die Energieeffizienzklasse des Produktes gemäß EU-Richtlinie 2010/30/EU. Mögliche Werte sind G, F, E, D, C, B, A, A+, A++, A+++. + + + A+++,A++,A+,A,B,C,D,E,F,G + + + Label 0 + + + Benutzerdefiniertes Label 0. Dient der individuellen Gruppierung von Produkten. + + + Label 1 + + + Benutzerdefiniertes Label 1. Dient der individuellen Gruppierung von Produkten. + + + Label 2 + + + Benutzerdefiniertes Label 2. Dient der individuellen Gruppierung von Produkten. + + + Label 3 + + + Benutzerdefiniertes Label 3. Dient der individuellen Gruppierung von Produkten. + + + Label 4 + + + Benutzerdefiniertes Label 4. Dient der individuellen Gruppierung von Produkten. + \ No newline at end of file diff --git a/src/Plugins/SmartStore.GoogleMerchantCenter/Localization/resources.en-us.xml b/src/Plugins/SmartStore.GoogleMerchantCenter/Localization/resources.en-us.xml index a80721be22..3b75a8c306 100644 --- a/src/Plugins/SmartStore.GoogleMerchantCenter/Localization/resources.en-us.xml +++ b/src/Plugins/SmartStore.GoogleMerchantCenter/Localization/resources.en-us.xml @@ -37,24 +37,9 @@ Google Category - - Gender - - - Age group - - - Color - - - Size - - - Material - - - Pattern - + + Specifies the Google category corresponding to the product. Mandatory. + Additional images @@ -148,12 +133,6 @@ The pattern or graphic print featured on a product. Usefull for clothes for instance. - - Only online available - - - Check the box if products can only be purchased online. - Empty @@ -196,4 +175,61 @@ Activate this option if you want to export the base price of the product. + + Multipack + + + Number of identical products in a merchant defined multipack. Must be greater than 1. + + + Bundle + + + Merchant defined product package consisting of one main and several accessories or add-ons. + + + Adult + + + Product, which is intended only for adult users. + + + Energy efficiency + + + The energy efficiency class of the product in accordance with EU directive 2010/30/EU. Possible values are G, F, E, D, C, B, A, A +, A++, A+++. + + + A+++,A++,A+,A,B,C,D,E,F,G + + + Label 0 + + + Custom label 0 serves the individual grouping of products. + + + Label 1 + + + Custom label 1 serves the individual grouping of products. + + + Label 2 + + + Custom label 2 serves the individual grouping of products. + + + Label 3 + + + Custom label 3 serves the individual grouping of products. + + + Label 4 + + + Custom label 4 serves the individual grouping of products. + \ No newline at end of file diff --git a/src/Plugins/SmartStore.GoogleMerchantCenter/Models/FeedGoogleMerchantCenterModel.cs b/src/Plugins/SmartStore.GoogleMerchantCenter/Models/FeedGoogleMerchantCenterModel.cs index 0ec41770fe..36c5f02799 100644 --- a/src/Plugins/SmartStore.GoogleMerchantCenter/Models/FeedGoogleMerchantCenterModel.cs +++ b/src/Plugins/SmartStore.GoogleMerchantCenter/Models/FeedGoogleMerchantCenterModel.cs @@ -1,5 +1,6 @@ using System.ComponentModel; using System.ComponentModel.DataAnnotations; +using System.Text; using Newtonsoft.Json; using SmartStore.Core.Domain.Catalog; using SmartStore.Web.Framework; @@ -18,10 +19,12 @@ public string AvailableGoogleCategoriesAsJson { if (AvailableGoogleCategories != null && AvailableGoogleCategories.Length > 0) return JsonConvert.SerializeObject(AvailableGoogleCategories); - return ""; + return "[ ]"; } } + public string[] EnergyEfficiencyClasses { get; set; } + [SmartResourceDisplayName("Plugins.Feed.Froogle.SearchProductName")] public string SearchProductName { get; set; } @@ -29,7 +32,6 @@ public string AvailableGoogleCategoriesAsJson public string SearchIsTouched { get; set; } } - public class GoogleProductModel : ModelBase { public int TotalCount { get; set; } @@ -74,35 +76,66 @@ public string ProductTypeLabelHint [SmartResourceDisplayName("Plugins.Feed.Froogle.Products.GoogleCategory")] public string Taxonomy { get; set; } - [SmartResourceDisplayName("Plugins.Feed.Froogle.Products.Gender")] + [SmartResourceDisplayName("Plugins.Feed.Froogle.Gender")] public string Gender { get; set; } - [SmartResourceDisplayName("Plugins.Feed.Froogle.Products.AgeGroup")] + [SmartResourceDisplayName("Plugins.Feed.Froogle.AgeGroup")] public string AgeGroup { get; set; } - [SmartResourceDisplayName("Plugins.Feed.Froogle.Products.Color")] + [SmartResourceDisplayName("Plugins.Feed.Froogle.Color")] public string Color { get; set; } - [SmartResourceDisplayName("Plugins.Feed.Froogle.Products.Size")] + [SmartResourceDisplayName("Plugins.Feed.Froogle.Size")] public string Size { get; set; } - [SmartResourceDisplayName("Plugins.Feed.Froogle.Products.Material")] + [SmartResourceDisplayName("Plugins.Feed.Froogle.Material")] public string Material { get; set; } - [SmartResourceDisplayName("Plugins.Feed.Froogle.Products.Pattern")] + [SmartResourceDisplayName("Plugins.Feed.Froogle.Pattern")] public string Pattern { get; set; } [SmartResourceDisplayName("Common.Export")] public int Export { get; set; } [SmartResourceDisplayName("Common.Export")] - public bool Exporting + public bool Export2 { get { return Export != 0; } set { Export = (value ? 1 : 0); } } + [SmartResourceDisplayName("Plugins.Feed.Froogle.Multipack")] + public int Multipack { get; set; } + [SmartResourceDisplayName("Plugins.Feed.Froogle.Multipack")] + public int? Multipack2 + { + get { return Multipack > 0 ? Multipack : (int?)null; } + set { Multipack = (value ?? 0); } + } + + [SmartResourceDisplayName("Plugins.Feed.Froogle.IsBundle")] + public bool? IsBundle { get; set; } + + [SmartResourceDisplayName("Plugins.Feed.Froogle.IsAdult")] + public bool? IsAdult { get; set; } + + [SmartResourceDisplayName("Plugins.Feed.Froogle.EnergyEfficiencyClass")] + public string EnergyEfficiencyClass { get; set; } + + [SmartResourceDisplayName("Plugins.Feed.Froogle.CustomLabel0")] + public string CustomLabel0 { get; set; } + [SmartResourceDisplayName("Plugins.Feed.Froogle.CustomLabel1")] + public string CustomLabel1 { get; set; } + [SmartResourceDisplayName("Plugins.Feed.Froogle.CustomLabel2")] + public string CustomLabel2 { get; set; } + [SmartResourceDisplayName("Plugins.Feed.Froogle.CustomLabel3")] + public string CustomLabel3 { get; set; } + [SmartResourceDisplayName("Plugins.Feed.Froogle.CustomLabel4")] + public string CustomLabel4 { get; set; } + public string GenderLocalize { get; set; } public string AgeGroupLocalize { get; set; } - public string ExportingLocalize { get; set; } + public string Export2Localize { get; set; } + public string IsBundleLocalize { get; set; } + public string IsAdultLocalize { get; set; } } } \ No newline at end of file diff --git a/src/Plugins/SmartStore.GoogleMerchantCenter/Models/ProfileConfigurationModel.cs b/src/Plugins/SmartStore.GoogleMerchantCenter/Models/ProfileConfigurationModel.cs index 6b96944375..69d81d50dd 100644 --- a/src/Plugins/SmartStore.GoogleMerchantCenter/Models/ProfileConfigurationModel.cs +++ b/src/Plugins/SmartStore.GoogleMerchantCenter/Models/ProfileConfigurationModel.cs @@ -14,7 +14,6 @@ public class ProfileConfigurationModel public ProfileConfigurationModel() { Condition = "new"; - OnlineOnly = true; AdditionalImages = true; SpecialPrice = true; } @@ -66,9 +65,6 @@ public string AvailableGoogleCategoriesAsJson [SmartResourceDisplayName("Plugins.Feed.Froogle.Pattern")] public string Pattern { get; set; } - [SmartResourceDisplayName("Plugins.Feed.Froogle.OnlineOnly")] - public bool OnlineOnly { get; set; } - [SmartResourceDisplayName("Plugins.Feed.Froogle.ExpirationDays")] public int ExpirationDays { get; set; } diff --git a/src/Plugins/SmartStore.GoogleMerchantCenter/Providers/GmcXmlExportProvider.cs b/src/Plugins/SmartStore.GoogleMerchantCenter/Providers/GmcXmlExportProvider.cs index b43d2abe70..3a5cc536f6 100644 --- a/src/Plugins/SmartStore.GoogleMerchantCenter/Providers/GmcXmlExportProvider.cs +++ b/src/Plugins/SmartStore.GoogleMerchantCenter/Providers/GmcXmlExportProvider.cs @@ -157,6 +157,7 @@ protected override void Export(IExportExecuteContext context) { dynamic currency = context.Currency; string measureWeightSystemKey = ""; + var dateFormat = "yyyy-MM-ddTHH:mmZ"; var measureWeight = _measureService.GetMeasureWeightById(_measureSettings.BaseWeightId); @@ -287,9 +288,15 @@ protected override void Export(IExportExecuteContext context) writer.WriteElementString("g", "condition", _googleNamespace, condition); writer.WriteElementString("g", "availability", _googleNamespace, availability); + if (availability == "preorder" && entity.AvailableStartDateTimeUtc.HasValue && entity.AvailableStartDateTimeUtc.Value > DateTime.UtcNow) + { + var availabilityDate = entity.AvailableStartDateTimeUtc.Value.ToString(dateFormat); + + writer.WriteElementString("g", "availability_date", _googleNamespace, availabilityDate); + } + if (config.SpecialPrice && specialPrice.HasValue && entity.SpecialPriceStartDateTimeUtc.HasValue && entity.SpecialPriceEndDateTimeUtc.HasValue) { - var dateFormat = "yyyy-MM-ddTHH:mmZ"; var specialPriceDate = "{0}/{1}".FormatInvariant( entity.SpecialPriceStartDateTimeUtc.Value.ToString(dateFormat), entity.SpecialPriceEndDateTimeUtc.Value.ToString(dateFormat)); @@ -321,7 +328,6 @@ protected override void Export(IExportExecuteContext context) writer.WriteCData("pattern", gmc != null && gmc.Pattern.HasValue() ? gmc.Pattern : config.Pattern, "g", _googleNamespace); writer.WriteCData("item_group_id", gmc != null && gmc.ItemGroupId.HasValue() ? gmc.ItemGroupId : "", "g", _googleNamespace); - writer.WriteElementString("g", "online_only", _googleNamespace, config.OnlineOnly ? "y" : "n"); writer.WriteElementString("g", "identifier_exists", _googleNamespace, gtin.HasValue() || brand.HasValue() || mpn.HasValue() ? "TRUE" : "FALSE"); if (config.ExpirationDays > 0) @@ -360,11 +366,56 @@ protected override void Export(IExportExecuteContext context) } } + if (gmc != null && gmc.Multipack > 1) + { + writer.WriteElementString("g", "multipack", _googleNamespace, gmc.Multipack.ToString()); + } + + if (gmc != null && gmc.IsBundle.HasValue) + { + writer.WriteElementString("g", "is_bundle", _googleNamespace, gmc.IsBundle.Value ? "TRUE" : "FALSE"); + } + + if (gmc != null && gmc.IsAdult.HasValue) + { + writer.WriteElementString("g", "adult", _googleNamespace, gmc.IsAdult.Value ? "TRUE" : "FALSE"); + } + + if (gmc != null && gmc.EnergyEfficiencyClass.HasValue()) + { + writer.WriteElementString("g", "energy_efficiency_class", _googleNamespace, gmc.EnergyEfficiencyClass); + } + + if (gmc != null && gmc.CustomLabel0.HasValue()) + { + writer.WriteElementString("g", "custom_label_0", _googleNamespace, gmc.CustomLabel0); + } + + if (gmc != null && gmc.CustomLabel1.HasValue()) + { + writer.WriteElementString("g", "custom_label_1", _googleNamespace, gmc.CustomLabel1); + } + + if (gmc != null && gmc.CustomLabel2.HasValue()) + { + writer.WriteElementString("g", "custom_label_2", _googleNamespace, gmc.CustomLabel2); + } + + if (gmc != null && gmc.CustomLabel3.HasValue()) + { + writer.WriteElementString("g", "custom_label_3", _googleNamespace, gmc.CustomLabel3); + } + + if (gmc != null && gmc.CustomLabel4.HasValue()) + { + writer.WriteElementString("g", "custom_label_4", _googleNamespace, gmc.CustomLabel4); + } + ++context.RecordsSucceeded; } - catch (Exception exc) + catch (Exception exception) { - context.RecordException(exc, entity.Id); + context.RecordException(exception, entity.Id); } writer.WriteEndElement(); // item diff --git a/src/Plugins/SmartStore.GoogleMerchantCenter/Services/GoogleFeedService.cs b/src/Plugins/SmartStore.GoogleMerchantCenter/Services/GoogleFeedService.cs index 48d574215e..b5fab3af04 100644 --- a/src/Plugins/SmartStore.GoogleMerchantCenter/Services/GoogleFeedService.cs +++ b/src/Plugins/SmartStore.GoogleMerchantCenter/Services/GoogleFeedService.cs @@ -125,9 +125,36 @@ public void Upsert(int pk, string name, string value) case "Pattern": product.Pattern = value; break; - case "Exporting": + case "Export2": product.Export = value.ToBool(true); break; + case "Multipack2": + product.Multipack = value.ToInt(); + break; + case "IsBundle": + product.IsBundle = (value.IsEmpty() ? (bool?)null : value.ToBool()); + break; + case "IsAdult": + product.IsAdult = (value.IsEmpty() ? (bool?)null : value.ToBool()); + break; + case "EnergyEfficiencyClass": + product.EnergyEfficiencyClass = value; + break; + case "CustomLabel0": + product.CustomLabel0 = value; + break; + case "CustomLabel1": + product.CustomLabel1 = value; + break; + case "CustomLabel2": + product.CustomLabel2 = value; + break; + case "CustomLabel3": + product.CustomLabel3 = value; + break; + case "CustomLabel4": + product.CustomLabel4 = value; + break; } product.UpdatedOnUtc = utcNow; @@ -156,7 +183,8 @@ public GridModel GetGridModel(GridCommand command, string se string yes = T("Admin.Common.Yes"); string no = T("Admin.Common.No"); - // there's no way to share a context instance across repositories which makes GoogleProductObjectContext pretty useless here. + // there's no way to share a context instance across repositories in EF. + // so we have to fallback to pure SQL here to get the data paged and filtered. var whereClause = new StringBuilder("(NOT ([t2].[Deleted] = 1)) AND ([t2].[VisibleIndividually] = 1)"); @@ -181,11 +209,11 @@ public GridModel GetGridModel(GridCommand command, string se { // fastest possible paged data query sql = - "SELECT [TotalCount], [t3].[Id], [t3].[Name], [t3].[SKU], [t3].[ProductTypeId], [t3].[value] AS [Taxonomy], [t3].[value2] AS [Gender], [t3].[value3] AS [AgeGroup], [t3].[value4] AS [Color], [t3].[value5] AS [Size], [t3].[value6] AS [Material], [t3].[value7] AS [Pattern], [t3].[value8] AS [Export]" + + "SELECT [TotalCount], [t3].[Id], [t3].[Name], [t3].[SKU], [t3].[ProductTypeId], [t3].[value] AS [Taxonomy], [t3].[value2] AS [Gender], [t3].[value3] AS [AgeGroup], [t3].[value4] AS [Color], [t3].[value5] AS [Size], [t3].[value6] AS [Material], [t3].[value7] AS [Pattern], [t3].[value8] AS [Export], [t3].[value9] AS [Multipack], [t3].[value10] AS [IsBundle], [t3].[value11] AS [IsAdult], [t3].[value12] AS [EnergyEfficiencyClass], [t3].[value13] AS [CustomLabel0], [t3].[value14] AS [CustomLabel1], [t3].[value15] AS [CustomLabel2], [t3].[value16] AS [CustomLabel3], [t3].[value17] AS [CustomLabel4]" + " FROM (" + - " SELECT COUNT(id) OVER() [TotalCount], ROW_NUMBER() OVER (ORDER BY [t2].[Name]) AS [ROW_NUMBER], [t2].[Id], [t2].[Name], [t2].[SKU], [t2].[ProductTypeId], [t2].[value], [t2].[value2], [t2].[value3], [t2].[value4], [t2].[value5], [t2].[value6], [t2].[value7], [t2].[value8]" + + " SELECT COUNT(id) OVER() [TotalCount], ROW_NUMBER() OVER (ORDER BY [t2].[Name]) AS [ROW_NUMBER], [t2].[Id], [t2].[Name], [t2].[SKU], [t2].[ProductTypeId], [t2].[value], [t2].[value2], [t2].[value3], [t2].[value4], [t2].[value5], [t2].[value6], [t2].[value7], [t2].[value8], [t2].[value9], [t2].[value10], [t2].[value11], [t2].[value12], [t2].[value13], [t2].[value14], [t2].[value15], [t2].[value16], [t2].[value17]" + " FROM (" + - " SELECT [t0].[Id], [t0].[Name], [t0].[SKU], [t0].[ProductTypeId], [t1].[Taxonomy] AS [value], [t1].[Gender] AS [value2], [t1].[AgeGroup] AS [value3], [t1].[Color] AS [value4], [t1].[Size] AS [value5], [t1].[Material] AS [value6], [t1].[Pattern] AS [value7], COALESCE([t1].[Export],1) AS [value8], [t0].[Deleted], [t0].[VisibleIndividually], [t1].[IsTouched]" + + " SELECT [t0].[Id], [t0].[Name], [t0].[SKU], [t0].[ProductTypeId], [t1].[Taxonomy] AS [value], [t1].[Gender] AS [value2], [t1].[AgeGroup] AS [value3], [t1].[Color] AS [value4], [t1].[Size] AS [value5], [t1].[Material] AS [value6], [t1].[Pattern] AS [value7], COALESCE([t1].[Export],1) AS [value8], COALESCE([t1].[Multipack],0) AS [value9], [t1].[IsBundle] AS [value10], [t1].[IsAdult] AS [value11], [t1].[EnergyEfficiencyClass] AS [value12], [t1].[CustomLabel0] AS [value13], [t1].[CustomLabel1] AS [value14], [t1].[CustomLabel2] AS [value15], [t1].[CustomLabel3] AS [value16], [t1].[CustomLabel4] AS [value17], [t0].[Deleted], [t0].[VisibleIndividually], [t1].[IsTouched]" + " FROM [Product] AS [t0]" + " LEFT OUTER JOIN [GoogleProduct] AS [t1] ON [t0].[Id] = [t1].[ProductId]" + " ) AS [t2]" + @@ -198,9 +226,9 @@ public GridModel GetGridModel(GridCommand command, string se { // OFFSET... FETCH NEXT requires SQL Server 2012 or SQL CE 4 sql = - "SELECT [t2].[Id], [t2].[Name], [t2].[SKU], [t2].[ProductTypeId], [t2].[value] AS [Taxonomy], [t2].[value2] AS [Gender], [t2].[value3] AS [AgeGroup], [t2].[value4] AS [Color], [t2].[value5] AS [Size], [t2].[value6] AS [Material], [t2].[value7] AS [Pattern], [t2].[value8] AS [Export]" + + "SELECT [t2].[Id], [t2].[Name], [t2].[SKU], [t2].[ProductTypeId], [t2].[value] AS [Taxonomy], [t2].[value2] AS [Gender], [t2].[value3] AS [AgeGroup], [t2].[value4] AS [Color], [t2].[value5] AS [Size], [t2].[value6] AS [Material], [t2].[value7] AS [Pattern], [t2].[value8] AS [Export], [t2].[value9] AS [Multipack], [t2].[value10] AS [IsBundle], [t2].[value11] AS [IsAdult], [t2].[value12] AS [EnergyEfficiencyClass], [t2].[value13] AS [CustomLabel0], [t2].[value14] AS [CustomLabel1], [t2].[value15] AS [CustomLabel2], [t2].[value16] AS [CustomLabel3], [t2].[value17] AS [CustomLabel4]" + " FROM (" + - " SELECT [t0].[Id], [t0].[Name], [t0].[SKU], [t0].[ProductTypeId], [t1].[Taxonomy] AS [value], [t1].[Gender] AS [value2], [t1].[AgeGroup] AS [value3], [t1].[Color] AS [value4], [t1].[Size] AS [value5], [t1].[Material] AS [value6], [t1].[Pattern] AS [value7], COALESCE([t1].[Export],1) AS [value8], [t0].[Deleted], [t0].[VisibleIndividually], [t1].[IsTouched] AS [IsTouched]" + + " SELECT [t0].[Id], [t0].[Name], [t0].[SKU], [t0].[ProductTypeId], [t1].[Taxonomy] AS [value], [t1].[Gender] AS [value2], [t1].[AgeGroup] AS [value3], [t1].[Color] AS [value4], [t1].[Size] AS [value5], [t1].[Material] AS [value6], [t1].[Pattern] AS [value7], COALESCE([t1].[Export],1) AS [value8], COALESCE([t1].[Multipack],0) AS [value9], [t1].[IsBundle] AS [value10], [t1].[IsAdult] AS [value11], [t1].[EnergyEfficiencyClass] AS [value12], [t1].[CustomLabel0] AS [value13], [t1].[CustomLabel1] AS [value14], [t1].[CustomLabel2] AS [value15], [t1].[CustomLabel3] AS [value16], [t1].[CustomLabel4] AS [value17], [t0].[Deleted], [t0].[VisibleIndividually], [t1].[IsTouched] AS [IsTouched]" + " FROM [Product] AS [t0]" + " LEFT OUTER JOIN [GoogleProduct] AS [t1] ON [t0].[Id] = [t1].[ProductId]" + " ) AS [t2]" + @@ -232,7 +260,17 @@ public GridModel GetGridModel(GridCommand command, string se if (x.AgeGroup.HasValue()) x.AgeGroupLocalize = T("Plugins.Feed.Froogle.AgeGroup" + textInfo.ToTitleCase(x.AgeGroup)); - x.ExportingLocalize = (x.Export == 0 ? no : yes); + x.Export2Localize = (x.Export == 0 ? no : yes); + + if (x.IsBundle.HasValue) + x.IsBundleLocalize = (x.IsBundle.Value ? yes : no); + else + x.IsBundleLocalize = null; + + if (x.IsAdult.HasValue) + x.IsAdultLocalize = (x.IsAdult.Value ? yes : no); + else + x.IsAdultLocalize = null; }); model.Data = data; diff --git a/src/Plugins/SmartStore.GoogleMerchantCenter/SmartStore.GoogleMerchantCenter.csproj b/src/Plugins/SmartStore.GoogleMerchantCenter/SmartStore.GoogleMerchantCenter.csproj index aa2b7dca53..f027f7dd39 100644 --- a/src/Plugins/SmartStore.GoogleMerchantCenter/SmartStore.GoogleMerchantCenter.csproj +++ b/src/Plugins/SmartStore.GoogleMerchantCenter/SmartStore.GoogleMerchantCenter.csproj @@ -169,6 +169,10 @@ 201504211854125_IsActive.cs + + + 201601061649324_IsBundle.cs + @@ -218,6 +222,9 @@ 201504211854125_IsActive.cs + + 201601061649324_IsBundle.cs + diff --git a/src/Plugins/SmartStore.GoogleMerchantCenter/Views/FeedGoogleMerchantCenter/Configure.cshtml b/src/Plugins/SmartStore.GoogleMerchantCenter/Views/FeedGoogleMerchantCenter/Configure.cshtml index 6312648112..d91ec16571 100644 --- a/src/Plugins/SmartStore.GoogleMerchantCenter/Views/FeedGoogleMerchantCenter/Configure.cshtml +++ b/src/Plugins/SmartStore.GoogleMerchantCenter/Views/FeedGoogleMerchantCenter/Configure.cshtml @@ -3,7 +3,6 @@ @using SmartStore.GoogleMerchantCenter.Models; @using SmartStore.GoogleMerchantCenter.Providers; @using SmartStore.Web.Framework; -@using SmartStore.Web.Framework.Plugins; @using Telerik.Web.Mvc.UI; @using SmartStore.Web.Framework.UI; @@ -53,7 +52,8 @@ @Html.SmartLabelFor(m => m.SearchIsTouched) - @Html.DropDownList("SearchIsTouched", new List { + @Html.DropDownList("SearchIsTouched", new List + { new SelectListItem { Text = T("Common.Unspecified"), Value = "" }, new SelectListItem { Text = T("Plugins.Feed.Froogle.SearchIsTouched.Touched"), Value = "touched" }, new SelectListItem { Text = T("Plugins.Feed.Froogle.SearchIsTouched.Untouched"), Value = "untouched" } @@ -82,25 +82,56 @@ }) .Columns(c => { - c.Bound(x => x.ProductId).ReadOnly().Visible(false); + c.Bound(x => x.ProductId) + .ReadOnly() + .Visible(false); c.Bound(x => x.Name) - .ReadOnly().Visible(true).Width(420) + .ReadOnly().Visible(true) .Template(x => @Html.LabeledProductName(x.ProductId, x.Name, x.ProductTypeName, x.ProductTypeLabelHint)) .ClientTemplate(@Html.LabeledProductName("ProductId", "Name")); - c.Bound(x => x.SKU).ReadOnly().Visible(true); - c.Bound(x => x.Exporting).ClientTemplate(Html.XEditableLink("Exporting", "select2")); - c.Bound(x => x.Taxonomy).ClientTemplate(Html.XEditableLink("Taxonomy", "typeahead")); - c.Bound(x => x.Gender).ClientTemplate(Html.XEditableLink("Gender", "select2")).Width(100); - c.Bound(x => x.AgeGroup).ClientTemplate(Html.XEditableLink("AgeGroup", "select2")).Width(100); - c.Bound(x => x.Color).ClientTemplate(Html.XEditableLink("Color", "text")); - c.Bound(x => x.Size).ClientTemplate(Html.XEditableLink("Size", "text")); - c.Bound(x => x.Material).ClientTemplate(Html.XEditableLink("Material", "text")); - c.Bound(x => x.Pattern).ClientTemplate(Html.XEditableLink("Pattern", "text")); + c.Bound(x => x.SKU) + .ReadOnly() + .Visible(true); + c.Bound(x => x.Export2) + .ClientTemplate(Html.XEditableLink("Export2", "select2")); + c.Bound(x => x.Taxonomy) + .ClientTemplate(Html.XEditableLink("Taxonomy", "typeahead")); + c.Bound(x => x.Gender) + .ClientTemplate(Html.XEditableLink("Gender", "select2")); + c.Bound(x => x.AgeGroup) + .ClientTemplate(Html.XEditableLink("AgeGroup", "select2")); + c.Bound(x => x.IsAdult) + .ClientTemplate(Html.XEditableLink("IsAdult", "select2")); + c.Bound(x => x.Color) + .ClientTemplate(Html.XEditableLink("Color", "text")); + c.Bound(x => x.Size) + .ClientTemplate(Html.XEditableLink("Size", "text")); + c.Bound(x => x.Material) + .ClientTemplate(Html.XEditableLink("Material", "text")); + c.Bound(x => x.Pattern) + .ClientTemplate(Html.XEditableLink("Pattern", "text")); + c.Bound(x => x.Multipack2) + .ClientTemplate(Html.XEditableLink("Multipack2", "text")); + c.Bound(x => x.IsBundle) + .ClientTemplate(Html.XEditableLink("IsBundle", "select2")); + c.Bound(x => x.EnergyEfficiencyClass) + .ClientTemplate(Html.XEditableLink("EnergyEfficiencyClass", "select2")); + c.Bound(x => x.CustomLabel0) + .ClientTemplate(Html.XEditableLink("CustomLabel0", "text")); + c.Bound(x => x.CustomLabel1) + .ClientTemplate(Html.XEditableLink("CustomLabel1", "text")); + c.Bound(x => x.CustomLabel2) + .ClientTemplate(Html.XEditableLink("CustomLabel2", "text")); + c.Bound(x => x.CustomLabel3) + .ClientTemplate(Html.XEditableLink("CustomLabel3", "text")); + c.Bound(x => x.CustomLabel4) + .ClientTemplate(Html.XEditableLink("CustomLabel4", "text")); }) .ClientEvents(e => { e.OnDataBound("OnGridDataBound"); e.OnDataBinding("OnGridDataBinding"); + e.OnError("OnGridError"); }) .DataBinding(dataBinding => { @@ -127,6 +158,11 @@ return false; }); + function OnGridError(e) { + e.preventDefault(); + alert(e.XMLHttpRequest.responseText); + } + function OnGridDataBinding(e) { e.data = { searchProductName: $('#SearchProductName').val(), @@ -135,28 +171,32 @@ } function OnGridDataBound(e) { - var grid = $('#gmc-products-grid'), - options = { - emptytext: '@T("Plugins.Feed.Froogle.EmptyGridCell")', - url: '@Url.Action("GoogleProductEdit", "FeedGoogleMerchantCenter", new { Namespaces = "SmartStore.GoogleMerchantCenter.Controllers", area = GoogleMerchantCenterFeedPlugin.SystemName })' - }, - select2Options = { - placeholder: '@T("Plugins.Feed.Froogle.EmptyGridCell")', - minimumResultsForSearch: 20, - allowClear: true - }; + var grid = $('#gmc-products-grid'); + + var emptyCell = '@T("Plugins.Feed.Froogle.EmptyGridCell")'; + + var options = { + emptytext: emptyCell, + url: '@Url.Action("GoogleProductEdit", "FeedGoogleMerchantCenter", new { Namespaces = "SmartStore.GoogleMerchantCenter.Controllers", area = GoogleMerchantCenterFeedPlugin.SystemName })' + }; + var select2Options = { + placeholder: emptyCell, + minimumResultsForSearch: 20, + allowClear: true + }; + var boolSource = [ + { id: 'true', text: '@T("Admin.Common.Yes")' }, + { id: 'false', text: '@T("Admin.Common.No")' } + ]; - grid.find('a.edit-link-exporting').editable($.extend(options, { + grid.find('a.edit-link-export2').editable($.extend({}, options, { select2: { minimumResultsForSearch: 20 }, - source: [ - { id: 'true', text: '@T("Admin.Common.Yes")' }, - { id: 'false', text: '@T("Admin.Common.No")' } - ] + source: boolSource })); - grid.find('a.edit-link-gender').editable($.extend(options, { + grid.find('a.edit-link-gender').editable($.extend({}, options, { select2: select2Options, source: [ { id: 'male', text: '@T("Plugins.Feed.Froogle.GenderMale")' }, @@ -165,7 +205,7 @@ ] })); - grid.find('a.edit-link-agegroup').editable($.extend(options, { + grid.find('a.edit-link-agegroup').editable($.extend({}, options, { select2: select2Options, source: [ { id: 'adult', text: '@T("Plugins.Feed.Froogle.AgeGroupAdult").Text' }, @@ -173,6 +213,11 @@ ] })); + grid.find('a.edit-link-isadult').editable($.extend({}, options, { + select2: select2Options, + source: boolSource + })); + grid.find('a.edit-link-color').editable(options); grid.find('a.edit-link-size').editable(options); @@ -181,7 +226,46 @@ grid.find('a.edit-link-pattern').editable(options); - grid.find('a.edit-link-taxonomy').editable($.extend(options, { + grid.find('a.edit-link-multipack2').editable($.extend({}, options, { + validate: function(value) { + if (value.length !== 0) { + var regex = /^[0-9]+$/; + if (!regex.test(value)) { + return '@T("Admin.System.Warnings.DigitsOnly")'; + } + } + return null; + } + })); + + grid.find('a.edit-link-isbundle').editable($.extend({}, options, { + select2: select2Options, + source: boolSource + })); + + grid.find('a.edit-link-energyefficiencyclass').editable($.extend({}, options, { + select2: select2Options, + source: [ + @if (Model.EnergyEfficiencyClasses != null && Model.EnergyEfficiencyClasses.Length > 0) + { + foreach (var str in Model.EnergyEfficiencyClasses.Select(x => x.Replace("'", "\""))) + { + { id: '@str', text: '@str' }, + } + } + ] + })); + + grid.find('a.edit-link-customlabel0').editable(options); + grid.find('a.edit-link-customlabel1').editable(options); + grid.find('a.edit-link-customlabel2').editable(options); + grid.find('a.edit-link-customlabel3').editable(options); + grid.find('a.edit-link-customlabel4').editable(options); + + grid.find('a.edit-link-taxonomy').editable($.extend({}, options, { + select2: { + minimumResultsForSearch: 20 + }, source: @Html.Raw(Model.AvailableGoogleCategoriesAsJson) })); } diff --git a/src/Plugins/SmartStore.GoogleMerchantCenter/Views/FeedGoogleMerchantCenter/ProductEditTab.cshtml b/src/Plugins/SmartStore.GoogleMerchantCenter/Views/FeedGoogleMerchantCenter/ProductEditTab.cshtml index fa3273da09..c20ef9acd7 100644 --- a/src/Plugins/SmartStore.GoogleMerchantCenter/Views/FeedGoogleMerchantCenter/ProductEditTab.cshtml +++ b/src/Plugins/SmartStore.GoogleMerchantCenter/Views/FeedGoogleMerchantCenter/ProductEditTab.cshtml @@ -6,24 +6,24 @@ - } - + if (ViewBag.RefreshPage == true) + { + + } - +
@@ -51,7 +49,7 @@ @Html.SmartLabelFor(model => model.SearchManufacturerId) @@ -59,7 +57,7 @@ @Html.SmartLabelFor(model => model.SearchProductTypeId) @@ -71,8 +69,9 @@
@Html.SmartLabelFor(model => model.SearchProductName) @@ -43,7 +41,7 @@ @Html.SmartLabelFor(model => model.SearchCategoryId) - @Html.DropDownList("SearchCategoryId", Model.AvailableCategories, T("Admin.Common.All").Text) + @Html.DropDownList("SearchCategoryId", Model.AvailableCategories, T("Admin.Common.All"))
- @Html.DropDownList("SearchManufacturerId", Model.AvailableManufacturers, T("Admin.Common.All").Text) + @Html.DropDownList("SearchManufacturerId", Model.AvailableManufacturers, T("Admin.Common.All"))
- @Html.DropDownList("SearchProductTypeId", Model.AvailableProductTypes) + @Html.DropDownList("SearchProductTypeId", Model.AvailableProductTypes, T("Admin.Common.All"))
-

-

+ +

+
diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Category/Tree.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Category/Tree.cshtml index 68162d1e32..1f3d747077 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Category/Tree.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Category/Tree.cshtml @@ -15,26 +15,29 @@ -@using (Html.BeginForm()) +@if (Model.AvailableStores.Count > 1) { - - - - - - - - - -
- @Html.SmartLabelFor(model => model.SearchStoreId) - - @Html.DropDownList("SearchStoreId", Model.AvailableStores) -
-   - - -
+ using (Html.BeginForm()) + { + + + + + + + + + +
+ @Html.SmartLabelFor(model => model.SearchStoreId) + + @Html.DropDownList("SearchStoreId", Model.AvailableStores, T("Admin.Common.All")) +
+   + + +
+ } }

diff --git a/src/Presentation/SmartStore.Web/Administration/Views/ContentSlider/Index.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/ContentSlider/Index.cshtml index 51251e2491..e847170de8 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/ContentSlider/Index.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/ContentSlider/Index.cshtml @@ -120,24 +120,27 @@ - - - - - - - - - -
- @Html.SmartLabelFor(model => model.SearchStoreId) - - @Html.DropDownList("SearchStoreId", Model.AvailableStores) -
-   - - -
+ if (Model.AvailableStores.Count > 1) + { + + + + + + + + + +
+ @Html.SmartLabelFor(model => model.SearchStoreId) + + @Html.DropDownList("SearchStoreId", Model.AvailableStores, T("Admin.Common.All")) +
+   + + +
+ }
@@ -164,7 +167,7 @@ .Width(100) .Template(x => @Html.SymbolForBool(x.LimitedToStores)) .ClientTemplate(@Html.SymbolForBool("LimitedToStores")) - .Hidden(Model.StoreCount <= 1) + .Hidden(Model.AvailableStores.Count <= 1) .Centered(); columns.Bound(x => x.Published) .Width(100) diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Customer/_ReportBestCustomersByNumberOfOrders.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Customer/_ReportBestCustomersByNumberOfOrders.cshtml index 98165844ae..919a1af379 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Customer/_ReportBestCustomersByNumberOfOrders.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Customer/_ReportBestCustomersByNumberOfOrders.cshtml @@ -1,59 +1,59 @@ @model BestCustomersReportModel - @using Telerik.Web.Mvc.UI - - - - - - - - - - - - - - - - - - - - - - - - - -
- @Html.SmartLabelFor(model => model.StartDate) - - @Html.EditorFor(model => model.StartDate) -
- @Html.SmartLabelFor(model => model.EndDate) - - @Html.EditorFor(model => Model.EndDate) -
- @Html.SmartLabelFor(model => model.OrderStatusId) - - @Html.DropDownList("OrderStatusId", Model.AvailableOrderStatuses) -
- @Html.SmartLabelFor(model => model.PaymentStatusId) - - @Html.DropDownList("PaymentStatusId", Model.AvailablePaymentStatuses) -
- @Html.SmartLabelFor(model => model.ShippingStatusId) - - @Html.DropDownList("ShippingStatusId", Model.AvailableShippingStatuses) -
-   - - -
-

-

+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ @Html.SmartLabelFor(model => model.StartDate) + + @Html.EditorFor(model => model.StartDate) +
+ @Html.SmartLabelFor(model => model.EndDate) + + @Html.EditorFor(model => Model.EndDate) +
+ @Html.SmartLabelFor(model => model.OrderStatusId) + + @Html.DropDownList("OrderStatusId", Model.AvailableOrderStatuses, T("Admin.Common.All")) +
+ @Html.SmartLabelFor(model => model.PaymentStatusId) + + @Html.DropDownList("PaymentStatusId", Model.AvailablePaymentStatuses, T("Admin.Common.All")) +
+ @Html.SmartLabelFor(model => model.ShippingStatusId) + + @Html.DropDownList("ShippingStatusId", Model.AvailableShippingStatuses, T("Admin.Common.All")) +
+   + + +
+ +

+
diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Customer/_ReportBestCustomersByOrderTotal.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Customer/_ReportBestCustomersByOrderTotal.cshtml index 13c0f4570f..af0e21e9bb 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Customer/_ReportBestCustomersByOrderTotal.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Customer/_ReportBestCustomersByOrderTotal.cshtml @@ -4,7 +4,7 @@ @using (Html.BeginForm()) { - +
@@ -34,7 +34,7 @@ @Html.SmartLabelFor(model => model.PaymentStatusId) @@ -42,7 +42,7 @@ @Html.SmartLabelFor(model => model.ShippingStatusId) @@ -54,8 +54,9 @@
@Html.SmartLabelFor(model => model.StartDate) @@ -26,7 +26,7 @@ @Html.SmartLabelFor(model => model.OrderStatusId) - @Html.DropDownList("OrderStatusId", Model.AvailableOrderStatuses) + @Html.DropDownList("OrderStatusId", Model.AvailableOrderStatuses, T("Admin.Common.All"))
- @Html.DropDownList("PaymentStatusId", Model.AvailablePaymentStatuses) + @Html.DropDownList("PaymentStatusId", Model.AvailablePaymentStatuses, T("Admin.Common.All"))
- @Html.DropDownList("ShippingStatusId", Model.AvailableShippingStatuses) + @Html.DropDownList("ShippingStatusId", Model.AvailableShippingStatuses, T("Admin.Common.All"))
-

-

+ +

+
diff --git a/src/Presentation/SmartStore.Web/Administration/Views/GiftCard/List.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/GiftCard/List.cshtml index fdcacfa7ea..96727f6ecb 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/GiftCard/List.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/GiftCard/List.cshtml @@ -1,9 +1,6 @@ @model GiftCardListModel @using Telerik.Web.Mvc.UI @{ - var gridPageSize = EngineContext.Current.Resolve().GridPageSize; - - //page title ViewBag.Title = T("Admin.GiftCards").Text; } @using (Html.BeginForm()) @@ -20,34 +17,36 @@ - - - - - - - - - - - + +
- @Html.SmartLabelFor(model => model.ActivatedId) - - @Html.DropDownListFor(model => model.ActivatedId, Model.ActivatedList) -
- @Html.SmartLabelFor(model => model.CouponCode) - - @Html.EditorFor(model => model.CouponCode) -
+ + + + + + + + + + + + - -
+ @Html.SmartLabelFor(model => model.ActivatedId) + + @Html.DropDownListFor(model => model.ActivatedId, Model.ActivatedList, T("Admin.Common.All")) +
+ @Html.SmartLabelFor(model => model.CouponCode) + + @Html.EditorFor(model => model.CouponCode) +
  - -
-

-

+ +
+ +

+
@@ -75,7 +74,7 @@ .HeaderTemplate("{0}".FormatWith(T("Admin.Common.Edit").Text)) .Filterable(false); }) - .Pageable(settings => settings.PageSize(gridPageSize).Position(GridPagerPosition.Both)) + .Pageable(settings => settings.PageSize(Model.GridPageSize).Position(GridPagerPosition.Both)) .DataBinding(dataBinding => dataBinding.Ajax().Select("GiftCardList", "GiftCard", Model)) .PreserveGridState() .EnableCustomBinding(true)) diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Log/List.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Log/List.cshtml index fbd9a6d127..05d898f309 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Log/List.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Log/List.cshtml @@ -21,7 +21,8 @@ - + +
diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Manufacturer/List.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Manufacturer/List.cshtml index c5f8fccc99..112515ff69 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Manufacturer/List.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Manufacturer/List.cshtml @@ -19,23 +19,35 @@ @Html.Widget("admin_button_toolbar_after") -
@Html.SmartLabelFor(model => model.CreatedOnFrom) @@ -51,7 +52,7 @@ @Html.SmartLabelFor(model => model.LogLevelId) - @Html.DropDownList("LogLevelId", Model.AvailableLogLevels) + @Html.DropDownList("LogLevelId", Model.AvailableLogLevels, T("Admin.Common.All"))
- - - - - + +
- @Html.SmartLabelFor(model => model.SearchManufacturerName) - - @Html.EditorFor(model => Model.SearchManufacturerName) -
+ + + + + @if (Model.AvailableStores.Count > 1) + { + + + + + } + - - + +
+ @Html.SmartLabelFor(model => model.SearchManufacturerName) + + @Html.EditorFor(model => Model.SearchManufacturerName) +
+ @Html.SmartLabelFor(model => model.SearchStoreId) + + @Html.DropDownListFor(model => model.SearchStoreId, Model.AvailableStores, T("Admin.Common.All")) +
  - -
+ +

@@ -57,11 +69,9 @@ .HtmlAttributes(new { style = "text-align:center" }) .HeaderHtmlAttributes(new { style = "text-align:center" }); columns.Bound(x => x.Name) - .Template(x => Html.ActionLink(x.Name, "Edit", new { id = x.Id })) .ClientTemplate("\"><#= Name #>"); columns.Bound(x => x.Published) .Width(160) - .Template(item => @Html.SymbolForBool(item.Published)) .ClientTemplate(@Html.SymbolForBool("Published")) .Centered(); columns.Bound(x => x.DisplayOrder) @@ -69,8 +79,8 @@ .Centered(); columns.Bound(x => x.LimitedToStores) .Width(160) - .Template(item => @Html.SymbolForBool(item.LimitedToStores)) .ClientTemplate(@Html.SymbolForBool("LimitedToStores")) + .Hidden(Model.AvailableStores.Count <= 1) .Centered(); }) .Pageable(settings => settings.PageSize(Model.GridPageSize).Position(GridPagerPosition.Both)) @@ -129,7 +139,8 @@ function onDataBinding(e) { var searchModel = { - SearchManufacturerName: $('#@Html.FieldIdFor(model => model.SearchManufacturerName)').val() + SearchManufacturerName: $('#@Html.FieldIdFor(model => model.SearchManufacturerName)').val(), + SearchStoreId: $('#@Html.FieldIdFor(model => model.SearchStoreId)').val() }; e.data = searchModel; } diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Manufacturer/ProductAddPopup.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Manufacturer/ProductAddPopup.cshtml index 15185b0812..d0864667b3 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Manufacturer/ProductAddPopup.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Manufacturer/ProductAddPopup.cshtml @@ -5,7 +5,6 @@ @{ var gridPageSize = EngineContext.Current.Resolve().GridPageSize; - //page title ViewBag.Title = T("Admin.Catalog.Manufacturers.Products.AddNew").Text; } @using Telerik.Web.Mvc.UI; @@ -17,17 +16,16 @@ - if (ViewBag.RefreshPage == true) - { - - } + if (ViewBag.RefreshPage == true) + { + + } - - +
@@ -49,7 +47,7 @@ @Html.SmartLabelFor(model => model.SearchManufacturerId) @@ -57,7 +55,7 @@ @Html.SmartLabelFor(model => model.SearchProductTypeId) @@ -69,8 +67,9 @@
@Html.SmartLabelFor(model => model.SearchProductName) @@ -41,7 +39,7 @@ @Html.SmartLabelFor(model => model.SearchCategoryId) - @Html.DropDownList("SearchCategoryId", Model.AvailableCategories, T("Admin.Common.All").Text) + @Html.DropDownList("SearchCategoryId", Model.AvailableCategories, T("Admin.Common.All"))
- @Html.DropDownList("SearchManufacturerId", Model.AvailableManufacturers, T("Admin.Common.All").Text) + @Html.DropDownList("SearchManufacturerId", Model.AvailableManufacturers, T("Admin.Common.All"))
- @Html.DropDownList("SearchProductTypeId", Model.AvailableProductTypes) + @Html.DropDownList("SearchProductTypeId", Model.AvailableProductTypes, T("Admin.Common.All"))
-

-

+ +

+ - - - - + @if (Model.AvailableStores.Count > 1) + { + + + + + }
diff --git a/src/Presentation/SmartStore.Web/Administration/Views/MessageTemplate/List.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/MessageTemplate/List.cshtml index 29c941466b..ed38d5c49c 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/MessageTemplate/List.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/MessageTemplate/List.cshtml @@ -16,26 +16,29 @@ - - - - - - - - - -
- @Html.SmartLabelFor(model => model.SearchStoreId) - - @Html.DropDownList("SearchStoreId", Model.AvailableStores) -
-   - - -
+@if (Model.AvailableStores.Count > 1) +{ + + + + + + + + + +
+ @Html.SmartLabelFor(model => model.SearchStoreId) + + @Html.DropDownList("SearchStoreId", Model.AvailableStores, T("Admin.Common.All")) +
+   + + +
+}

diff --git a/src/Presentation/SmartStore.Web/Administration/Views/News/List.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/News/List.cshtml index dfcd240b18..aa82033bf7 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/News/List.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/News/List.cshtml @@ -25,26 +25,29 @@ - - - - - - - - - -
- @Html.SmartLabelFor(model => model.SearchStoreId) - - @Html.DropDownList("SearchStoreId", Model.AvailableStores) -
-   - - -
+@if (Model.AvailableStores.Count > 1) +{ + + + + + + + + + +
+ @Html.SmartLabelFor(model => model.SearchStoreId) + + @Html.DropDownList("SearchStoreId", Model.AvailableStores, T("Admin.Common.All")) +
+   + + +
+}

@@ -81,6 +84,7 @@ columns.Bound(x => x.LimitedToStores) .Template(item => @Html.SymbolForBool(item.LimitedToStores)) .ClientTemplate(@Html.SymbolForBool("LimitedToStores")) + .Hidden(Model.AvailableStores.Count <= 1) .Centered(); columns.Bound(x => x.CreatedOn); }) diff --git a/src/Presentation/SmartStore.Web/Administration/Views/NewsLetterSubscription/List.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/NewsLetterSubscription/List.cshtml index 5953d03c49..da8b2d4fd5 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/NewsLetterSubscription/List.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/NewsLetterSubscription/List.cshtml @@ -24,14 +24,17 @@ @Html.EditorFor(model => Model.SearchEmail)
- @Html.SmartLabelFor(model => model.StoreId) - - @Html.DropDownList("StoreId", Model.AvailableStores) -
+ @Html.SmartLabelFor(model => model.StoreId) + + @Html.DropDownList("StoreId", Model.AvailableStores, T("Admin.Common.All")) +
  @@ -64,6 +67,7 @@ .Centered() .Width(100); columns.Bound(x => x.StoreName) + .Hidden(Model.AvailableStores.Count <= 1) .ReadOnly(); columns.Bound(x => x.CreatedOn) .ReadOnly() diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Order/AddProductToOrder.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Order/AddProductToOrder.cshtml index 574db39957..2c99ed1a86 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Order/AddProductToOrder.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Order/AddProductToOrder.cshtml @@ -2,7 +2,6 @@ @{ var gridPageSize = EngineContext.Current.Resolve().GridPageSize; - //page title ViewBag.Title = string.Format(T("Admin.Orders.Products.AddNew.Title1").Text, Model.OrderId); } @using Telerik.Web.Mvc.UI; @@ -19,7 +18,7 @@ @T("Admin.Orders.Products.AddNew.Note1") - +
@@ -41,7 +40,7 @@ @Html.SmartLabelFor(model => model.SearchManufacturerId) @@ -49,7 +48,7 @@ @Html.SmartLabelFor(model => model.SearchProductTypeId) @@ -63,7 +62,9 @@
@Html.SmartLabelFor(model => model.SearchProductName) @@ -33,7 +32,7 @@ @Html.SmartLabelFor(model => model.SearchCategoryId) - @Html.DropDownList("SearchCategoryId", Model.AvailableCategories, T("Admin.Common.All").Text) + @Html.DropDownList("SearchCategoryId", Model.AvailableCategories, T("Admin.Common.All"))
- @Html.DropDownList("SearchManufacturerId", Model.AvailableManufacturers, T("Admin.Common.All").Text) + @Html.DropDownList("SearchManufacturerId", Model.AvailableManufacturers, T("Admin.Common.All"))
- @Html.DropDownList("SearchProductTypeId", Model.AvailableProductTypes) + @Html.DropDownList("SearchProductTypeId", Model.AvailableProductTypes, T("Admin.Common.All"))
+

+
diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Order/BestsellersReport.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Order/BestsellersReport.cshtml index c6fb84b696..e035acfa1e 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Order/BestsellersReport.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Order/BestsellersReport.cshtml @@ -1,7 +1,6 @@ @model BestsellersReportModel @using Telerik.Web.Mvc.UI @{ - //page title ViewBag.Title = T("Admin.SalesReport.Bestsellers").Text; } @using (Html.BeginForm()) @@ -14,7 +13,8 @@
- + +
@@ -44,7 +44,7 @@ @Html.SmartLabelFor(model => model.PaymentStatusId) @@ -56,8 +56,9 @@
@Html.SmartLabelFor(model => model.StartDate) @@ -36,7 +36,7 @@ @Html.SmartLabelFor(model => model.OrderStatusId) - @Html.DropDownList("OrderStatusId", Model.AvailableOrderStatuses) + @Html.DropDownList("OrderStatusId", Model.AvailableOrderStatuses, T("Admin.Common.All"))
- @Html.DropDownList("PaymentStatusId", Model.AvailablePaymentStatuses) + @Html.DropDownList("PaymentStatusId", Model.AvailablePaymentStatuses, T("Admin.Common.All"))
-

-

+ +

+ - @if (Model.StoreCount > 1) + @if (Model.AvailableStores.Count > 1) {
@@ -106,5 +107,4 @@ } - } \ No newline at end of file diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Order/List.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Order/List.cshtml index 47e12fdb99..af55c9bde6 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Order/List.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Order/List.cshtml @@ -97,7 +97,7 @@ @Html.DropDownList("ShippingStatusIds", Model.AvailableShippingStatuses, null, new { multiple = "multiple" })
@@ -176,7 +176,7 @@ columns.Bound(x => x.CustomerName); columns.Bound(x => x.CustomerEmail); columns.Bound(x => x.StoreName) - .Hidden(Model.StoreCount <= 1); + .Hidden(Model.AvailableStores.Count <= 1); columns.Bound(x => x.CreatedOn); columns.Bound(x => x.OrderTotal) .Width(180) diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Product/AssociatedProductAddPopup.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Product/AssociatedProductAddPopup.cshtml index b5fd79b0e4..a46a602417 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Product/AssociatedProductAddPopup.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Product/AssociatedProductAddPopup.cshtml @@ -27,7 +27,7 @@ } - +
@@ -49,23 +49,26 @@ @Html.SmartLabelFor(model => model.SearchManufacturerId) - - - - + @if (Model.AvailableStores.Count > 1) + { + + + + + } diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Product/BulkEdit.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Product/BulkEdit.cshtml index 6eb786b6ba..ebdea889fa 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Product/BulkEdit.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Product/BulkEdit.cshtml @@ -3,7 +3,6 @@ @{ var allString = T("Admin.Common.All").Text; - //page title ViewBag.Title = T("Admin.Catalog.BulkEdit").Text; } @using (Html.BeginForm()) @@ -38,7 +37,7 @@ @Html.DropDownList("SearchProductTypeId", Model.AvailableProductTypes, allString) - @if (Model.StoreCount > 1) + @if (Model.AvailableStores.Count > 1) {
@Html.SmartLabelFor(model => model.SearchProductName) @@ -41,7 +41,7 @@ @Html.SmartLabelFor(model => model.SearchCategoryId) - @Html.DropDownList("SearchCategoryId", Model.AvailableCategories, T("Admin.Common.All").Text) + @Html.DropDownList("SearchCategoryId", Model.AvailableCategories, T("Admin.Common.All"))
- @Html.DropDownList("SearchManufacturerId", Model.AvailableManufacturers, T("Admin.Common.All").Text) -
- @Html.SmartLabelFor(model => model.SearchStoreId) - - @Html.DropDownList("SearchStoreId", Model.AvailableStores) + @Html.DropDownList("SearchManufacturerId", Model.AvailableManufacturers, T("Admin.Common.All"))
+ @Html.SmartLabelFor(model => model.SearchStoreId) + + @Html.DropDownList("SearchStoreId", Model.AvailableStores, T("Admin.Common.All")) +
@Html.SmartLabelFor(model => model.SearchProductTypeId) - @Html.DropDownList("SearchProductTypeId", Model.AvailableProductTypes) + @Html.DropDownList("SearchProductTypeId", Model.AvailableProductTypes, T("Admin.Common.All"))
diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Product/BundleItemAddPopup.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Product/BundleItemAddPopup.cshtml index b31b86f3a2..490d650ce4 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Product/BundleItemAddPopup.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Product/BundleItemAddPopup.cshtml @@ -47,7 +47,7 @@ } - +
@@ -69,23 +69,26 @@ @Html.SmartLabelFor(model => model.SearchManufacturerId) - - - - + @if (Model.AvailableStores.Count > 1) + { + + + + + } diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Product/CrossSellProductAddPopup.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Product/CrossSellProductAddPopup.cshtml index ac06795dec..31f0e00244 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Product/CrossSellProductAddPopup.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Product/CrossSellProductAddPopup.cshtml @@ -5,7 +5,6 @@ @{ var gridPageSize = EngineContext.Current.Resolve().GridPageSize; - //page title ViewBag.Title = T("Admin.Catalog.Products.CrossSells.AddNew").Text; } @using Telerik.Web.Mvc.UI; @@ -27,7 +26,7 @@ } -
@Html.SmartLabelFor(model => model.SearchProductName) @@ -61,7 +61,7 @@ @Html.SmartLabelFor(model => model.SearchCategoryId) - @Html.DropDownList("SearchCategoryId", Model.AvailableCategories, T("Admin.Common.All").Text) + @Html.DropDownList("SearchCategoryId", Model.AvailableCategories, T("Admin.Common.All"))
- @Html.DropDownList("SearchManufacturerId", Model.AvailableManufacturers, T("Admin.Common.All").Text) -
- @Html.SmartLabelFor(model => model.SearchStoreId) - - @Html.DropDownList("SearchStoreId", Model.AvailableStores) + @Html.DropDownList("SearchManufacturerId", Model.AvailableManufacturers, T("Admin.Common.All"))
+ @Html.SmartLabelFor(model => model.SearchStoreId) + + @Html.DropDownList("SearchStoreId", Model.AvailableStores, T("Admin.Common.All")) +
@Html.SmartLabelFor(model => model.SearchProductTypeId) - @Html.DropDownList("SearchProductTypeId", Model.AvailableProductTypes) + @Html.DropDownList("SearchProductTypeId", Model.AvailableProductTypes, T("Admin.Common.All"))
+
@@ -49,23 +48,26 @@ @Html.SmartLabelFor(model => model.SearchManufacturerId) - - - - + @if (Model.AvailableStores.Count > 1) + { + + + + + } diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Product/List.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Product/List.cshtml index feb7fe9c84..1b18b8a636 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Product/List.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Product/List.cshtml @@ -44,7 +44,7 @@ @Html.DropDownListFor(model => model.SearchProductTypeId, Model.AvailableProductTypes, allString) - @if (Model.StoreCount > 1) + @if (Model.AvailableStores.Count > 1) { + + + + } + @if (Model.StoreCount > 1) + { + + + + + }
@Html.SmartLabelFor(model => model.SearchProductName) @@ -41,7 +40,7 @@ @Html.SmartLabelFor(model => model.SearchCategoryId) - @Html.DropDownList("SearchCategoryId", Model.AvailableCategories, T("Admin.Common.All").Text) + @Html.DropDownList("SearchCategoryId", Model.AvailableCategories, T("Admin.Common.All"))
- @Html.DropDownList("SearchManufacturerId", Model.AvailableManufacturers, T("Admin.Common.All").Text) -
- @Html.SmartLabelFor(model => model.SearchStoreId) - - @Html.DropDownList("SearchStoreId", Model.AvailableStores) + @Html.DropDownList("SearchManufacturerId", Model.AvailableManufacturers, T("Admin.Common.All"))
+ @Html.SmartLabelFor(model => model.SearchStoreId) + + @Html.DropDownList("SearchStoreId", Model.AvailableStores, T("Admin.Common.All")) +
@Html.SmartLabelFor(model => model.SearchProductTypeId) - @Html.DropDownList("SearchProductTypeId", Model.AvailableProductTypes) + @Html.DropDownList("SearchProductTypeId", Model.AvailableProductTypes, T("Admin.Common.All"))
@@ -170,7 +170,7 @@ .Sortable(false) .Template(item => @Html.SymbolForBool(item.LimitedToStores)) .ClientTemplate(@Html.SymbolForBool("LimitedToStores")) - .Hidden(Model.StoreCount <= 1) + .Hidden(Model.AvailableStores.Count <= 1) .Centered(); columns.Bound(x => x.CreatedOn); columns.Bound(x => x.UpdatedOn) diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Product/ProductAttributeValueLinkagePopup.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Product/ProductAttributeValueLinkagePopup.cshtml index 0ef7426f3c..62cde68c17 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Product/ProductAttributeValueLinkagePopup.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Product/ProductAttributeValueLinkagePopup.cshtml @@ -34,7 +34,7 @@ @Html.HiddenFor(model => model.ProductId) - +
@@ -56,23 +56,26 @@ @Html.SmartLabelFor(model => model.SearchManufacturerId) - - - - + @if (Model.AvailableStores.Count > 1) + { + + + + + } diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Product/RelatedProductAddPopup.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Product/RelatedProductAddPopup.cshtml index 7d5db715ca..a9a5b0b701 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Product/RelatedProductAddPopup.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Product/RelatedProductAddPopup.cshtml @@ -5,7 +5,6 @@ @{ var gridPageSize = EngineContext.Current.Resolve().GridPageSize; - //page title ViewBag.Title = T("Admin.Catalog.Products.RelatedProducts.AddNew").Text; } @using Telerik.Web.Mvc.UI; @@ -26,8 +25,7 @@ } - -
@Html.SmartLabelFor(model => model.SearchProductName) @@ -48,7 +48,7 @@ @Html.SmartLabelFor(model => model.SearchCategoryId) - @Html.DropDownList("SearchCategoryId", Model.AvailableCategories, T("Admin.Common.All").Text) + @Html.DropDownList("SearchCategoryId", Model.AvailableCategories, T("Admin.Common.All"))
- @Html.DropDownList("SearchManufacturerId", Model.AvailableManufacturers, T("Admin.Common.All").Text) -
- @Html.SmartLabelFor(model => model.SearchStoreId) - - @Html.DropDownList("SearchStoreId", Model.AvailableStores) + @Html.DropDownList("SearchManufacturerId", Model.AvailableManufacturers, T("Admin.Common.All"))
+ @Html.SmartLabelFor(model => model.SearchStoreId) + + @Html.DropDownList("SearchStoreId", Model.AvailableStores, T("Admin.Common.All")) +
@Html.SmartLabelFor(model => model.SearchProductTypeId) - @Html.DropDownList("SearchProductTypeId", Model.AvailableProductTypes) + @Html.DropDownList("SearchProductTypeId", Model.AvailableProductTypes, T("Admin.Common.All"))
+
@@ -49,23 +47,26 @@ @Html.SmartLabelFor(model => model.SearchManufacturerId) - - - - + @if (Model.AvailableStores.Count > 1) + { + + + + + } @@ -77,6 +78,7 @@
@Html.SmartLabelFor(model => model.SearchProductName) @@ -41,7 +39,7 @@ @Html.SmartLabelFor(model => model.SearchCategoryId) - @Html.DropDownList("SearchCategoryId", Model.AvailableCategories, T("Admin.Common.All").Text) + @Html.DropDownList("SearchCategoryId", Model.AvailableCategories, T("Admin.Common.All"))
- @Html.DropDownList("SearchManufacturerId", Model.AvailableManufacturers, T("Admin.Common.All").Text) -
- @Html.SmartLabelFor(model => model.SearchStoreId) - - @Html.DropDownList("SearchStoreId", Model.AvailableStores) + @Html.DropDownList("SearchManufacturerId", Model.AvailableManufacturers, T("Admin.Common.All"))
+ @Html.SmartLabelFor(model => model.SearchStoreId) + + @Html.DropDownList("SearchStoreId", Model.AvailableStores, T("Admin.Common.All")) +
@Html.SmartLabelFor(model => model.SearchProductTypeId) - @Html.DropDownList("SearchProductTypeId", Model.AvailableProductTypes) + @Html.DropDownList("SearchProductTypeId", Model.AvailableProductTypes, T("Admin.Common.All"))
+

diff --git a/src/Presentation/SmartStore.Web/Administration/Views/ReturnRequest/List.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/ReturnRequest/List.cshtml index e8f2359885..c9a62c9b5c 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/ReturnRequest/List.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/ReturnRequest/List.cshtml @@ -13,83 +13,88 @@ -
- - - - - - - - - - - - - +
- @Html.SmartLabelFor(model => model.SearchId) - - @Html.EditorFor(model => Model.SearchId) -
- @Html.SmartLabelFor(model => model.SearchStoreId) - - @Html.DropDownListFor(model => model.SearchStoreId, Model.AvailableStores) -
- @Html.SmartLabelFor(model => model.SearchReturnRequestStatusId) - - @Html.DropDownListFor(model => model.SearchReturnRequestStatusId, Model.AvailableReturnRequestStatus) -
+ + + + + @if (Model.AvailableStores.Count > 1) + { + + + + + } + + + + + - - + +
+ @Html.SmartLabelFor(model => model.SearchId) + + @Html.EditorFor(model => Model.SearchId) +
+ @Html.SmartLabelFor(model => model.SearchStoreId) + + @Html.DropDownListFor(model => model.SearchStoreId, Model.AvailableStores, T("Admin.Common.All")) +
+ @Html.SmartLabelFor(model => model.SearchReturnRequestStatusId) + + @Html.DropDownListFor(model => model.SearchReturnRequestStatusId, Model.AvailableReturnRequestStatus, T("Admin.Common.All")) +
  - -
+ +
+

@(Html.Telerik().Grid() - .Name("returnrequests-grid") - .Columns(columns => - { + .Name("returnrequests-grid") + .Columns(columns => + { columns.Bound(x => x.Id) .Centered() .Width(80); columns.Bound(x => x.ProductName) .Template(x => @Html.LabeledProductName(x.ProductId, x.ProductName, x.ProductTypeName, x.ProductTypeLabelHint)) .ClientTemplate(@Html.LabeledProductName("ProductId", "ProductName")); - columns.Bound(x => x.Quantity) + columns.Bound(x => x.Quantity) .Width(80) - .Centered(); - columns.Bound(x => x.CustomerId) - .Template(x => Html.ActionLink(T("Admin.Common.View").Text, "Edit", "Customer", new { id = x.CustomerId }, new { })) + .Centered(); + columns.Bound(x => x.CustomerId) + .Template(x => Html.ActionLink(T("Admin.Common.View").Text, "Edit", "Customer", new { id = x.CustomerId }, new { })) .ClientTemplate("\"><#= CustomerFullName #>"); - columns.Bound(x => x.OrderId) + columns.Bound(x => x.OrderId) .Width(80) - .Centered() - .Template(x => Html.ActionLink(T("Admin.Common.View").Text, "Edit", "Order", new { id = x.OrderId }, new { })) + .Centered() + .Template(x => Html.ActionLink(T("Admin.Common.View").Text, "Edit", "Order", new { id = x.OrderId }, new { })) .ClientTemplate("\"><#= OrderId #>"); columns.Bound(x => x.ReturnRequestStatusStr) - .Width(180); - columns.Bound(x => x.CreatedOn) .Width(180); - columns.Bound(x => x.StoreName); - columns.Bound(x => x.Id) + columns.Bound(x => x.CreatedOn) + .Width(180); + columns.Bound(x => x.StoreName) + .Hidden(Model.AvailableStores.Count <= 1); + columns.Bound(x => x.Id) .Width(100) - .Centered() - .Template(x => Html.ActionLink(T("Admin.Common.Edit").Text, "Edit", new { id = x.Id })) - .ClientTemplate("\">" + T("Admin.Common.Edit").Text + "") - .Title(T("Admin.Common.Edit").Text); - }) + .Centered() + .Template(x => Html.ActionLink(T("Admin.Common.Edit").Text, "Edit", new { id = x.Id })) + .ClientTemplate("\">" + T("Admin.Common.Edit").Text + "") + .Title(T("Admin.Common.Edit").Text); + }) .Pageable(settings => settings.PageSize(Model.GridPageSize).Position(GridPagerPosition.Both)) - .DataBinding(dataBinding => dataBinding.Ajax().Select("List", "ReturnRequest")) + .DataBinding(dataBinding => dataBinding.Ajax().Select("List", "ReturnRequest")) .ClientEvents(events => events.OnDataBinding("returnRequestGrid_onDataBinding")) .PreserveGridState() - .EnableCustomBinding(true)) + .EnableCustomBinding(true))
diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Topic/List.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Topic/List.cshtml index 08de2f50ab..18fda90102 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Topic/List.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Topic/List.cshtml @@ -16,26 +16,29 @@ - - - - - - - - - -
- @Html.SmartLabelFor(model => model.SearchStoreId) - - @Html.DropDownList("SearchStoreId", Model.AvailableStores) -
-   - - -
+@if (Model.AvailableStores.Count > 1) +{ + + + + + + + + + +
+ @Html.SmartLabelFor(model => model.SearchStoreId) + + @Html.DropDownList("SearchStoreId", Model.AvailableStores, T("Admin.Common.All")) +
+   + + +
+}

From 49da71aa6d88631916c7e9bf681732af73ff0f24 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Thu, 7 Jan 2016 18:56:27 +0100 Subject: [PATCH 138/626] Updated Google Analytics admin instructions Bulk update of string resources may fail because of outdated EfRepository.AutoCommitEnabledInternal state --- .../Localization/LocalizationService.cs | 9 +-------- .../Importer/NewsLetterSubscriptionImporter.cs | 4 +--- .../Localization/resources.de-de.xml | 11 ++++++----- .../Localization/resources.en-us.xml | 12 ++++++------ 4 files changed, 14 insertions(+), 22 deletions(-) diff --git a/src/Libraries/SmartStore.Services/Localization/LocalizationService.cs b/src/Libraries/SmartStore.Services/Localization/LocalizationService.cs index 31f83eb7dc..8610072e92 100644 --- a/src/Libraries/SmartStore.Services/Localization/LocalizationService.cs +++ b/src/Libraries/SmartStore.Services/Localization/LocalizationService.cs @@ -437,7 +437,6 @@ public virtual void ImportResourcesFromXml( foreach (var xel in nodes.Cast()) { - string name = xel.GetAttribute("Name").TrimSafe(); string value = ""; var valueNode = xel.SelectSingleNode("Value"); @@ -488,13 +487,7 @@ public virtual void ImportResourcesFromXml( _lsrRepository.InsertRange(toAdd, 500); toAdd.Clear(); - _lsrRepository.AutoCommitEnabled = null; - toUpdate.Each(x => - { - _lsrRepository.Update(x); - }); - - _lsrRepository.Context.SaveChanges(); + _lsrRepository.UpdateRange(toUpdate); toUpdate.Clear(); //clear cache diff --git a/src/Libraries/SmartStore.Services/Messages/Importer/NewsLetterSubscriptionImporter.cs b/src/Libraries/SmartStore.Services/Messages/Importer/NewsLetterSubscriptionImporter.cs index 5bf83c4755..17f3c10ed0 100644 --- a/src/Libraries/SmartStore.Services/Messages/Importer/NewsLetterSubscriptionImporter.cs +++ b/src/Libraries/SmartStore.Services/Messages/Importer/NewsLetterSubscriptionImporter.cs @@ -104,9 +104,7 @@ public void Execute(IImportExecuteContext context) toAdd.Clear(); // update modified subscribers - _subscriptionRepository.AutoCommitEnabled = null; - toUpdate.Each(x => _subscriptionRepository.Update(x)); - _subscriptionRepository.Context.SaveChanges(); + _subscriptionRepository.UpdateRange(toUpdate); toUpdate.Clear(); } catch (Exception exception) diff --git a/src/Plugins/SmartStore.GoogleAnalytics/Localization/resources.de-de.xml b/src/Plugins/SmartStore.GoogleAnalytics/Localization/resources.de-de.xml index 627698df96..d7f6055f92 100644 --- a/src/Plugins/SmartStore.GoogleAnalytics/Localization/resources.de-de.xml +++ b/src/Plugins/SmartStore.GoogleAnalytics/Localization/resources.de-de.xml @@ -5,13 +5,14 @@ Google Analytics ist ein kostenloser Statistikdienst von Google. Der Dienst erfasst Statistiken über Besucher und Ecommerce-Konversion auf Ihrer Webseite

+

Google Analytics ist ein kostenloser Statistikdienst von Google. Der Dienst erfasst Statistiken über Besucher und Ecommerce-Konversion auf Ihrer Webseite.

Führen Sie die folgenden Schritte aus um Google Analytics auf Ihrer Webseite einzubinden:

    -
  • erstellen Sie hier einen "Google Analytics"-Account und folgen Sie dem Wizard um Ihre Webseite zuzufügen
  • -
  • Kopieren Sie die "Google Analytics"-ID in das entspechende Feld in folgendem Formular
  • -
  • Kopieren Sie den Tracking-Code in die "Tracking-Code"-Box in folgendem Formular
  • -
  • KLicken Sie den "Speichern"-Button und Google Analytics wird in Ihre Webseite integriert
  • +
  • Erstellen Sie hier einen Google-Analytics-Account und folgen Sie dem Wizard um Ihre Webseite zuzufügen.
  • +
  • Kopieren Sie die Google-Analytics-ID in das entspechende Feld in folgendem Formular.
  • +
  • Kopieren Sie den Tracking-Code in die Tracking-Code-Box in folgendem Formular.
  • +
  • Klicken Sie den Speichern-Button.
  • +
  • Aktivieren Sie das Google Analytics Widget unter CMS > Widgets und Google Analytics wird in Ihre Webseite integriert.
]]>
diff --git a/src/Plugins/SmartStore.GoogleAnalytics/Localization/resources.en-us.xml b/src/Plugins/SmartStore.GoogleAnalytics/Localization/resources.en-us.xml index 2ac97f8895..d54877d501 100644 --- a/src/Plugins/SmartStore.GoogleAnalytics/Localization/resources.en-us.xml +++ b/src/Plugins/SmartStore.GoogleAnalytics/Localization/resources.en-us.xml @@ -5,14 +5,14 @@ Google Analytics is a free website stats tool from Google. It keeps track of statistics - about the visitors and ecommerce conversion on your website.

+

Google Analytics is a free website statistics tool from Google. It keeps track of statistics about the visitors and ecommerce conversion on your website.

Follow the next steps to enable Google Analytics integration:

    -
  • Create a Google Analytics account and follow the wizard to add your website
  • -
  • Copy the Google Analytics ID into the 'ID' box below
  • -
  • Copy the tracking code from Google Analytics into the 'Tracking Code' box below
  • -
  • Click the 'Save' button below and Google Analytics will be integrated into your store
  • +
  • Create a Google Analytics account and follow the wizard to add your website.
  • +
  • Copy the Google Analytics ID into the ID field below.
  • +
  • Copy the tracking code from Google Analytics into the Tracking Code field below.
  • +
  • Click the Save button below.
  • +
  • Activate the Google Analytics widget under CMS > Widgets to integrate Google Analytics into your store.
]]>
From df31f4f375026c4129096ca0cc0cecdfbb7a1863 Mon Sep 17 00:00:00 2001 From: Murat Cakir Date: Thu, 7 Jan 2016 20:22:45 +0100 Subject: [PATCH 139/626] TaskScheduler: logging the sweep call for debugging puposes (temp only) --- .../SmartStore.Core/Extensions/ConversionExtensions.cs | 6 +++++- src/Libraries/SmartStore.Services/Tasks/TaskScheduler.cs | 9 ++++++++- .../Controllers/TaskSchedulerController.cs | 2 +- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/Libraries/SmartStore.Core/Extensions/ConversionExtensions.cs b/src/Libraries/SmartStore.Core/Extensions/ConversionExtensions.cs index 64297abe9d..387bc9a614 100644 --- a/src/Libraries/SmartStore.Core/Extensions/ConversionExtensions.cs +++ b/src/Libraries/SmartStore.Core/Extensions/ConversionExtensions.cs @@ -239,7 +239,11 @@ public static string AsString(this Stream stream, Encoding encoding) // convert stream to string string result; - stream.Position = 0; + + if (stream.CanSeek) + { + stream.Position = 0; + } using (StreamReader sr = new StreamReader(stream, encoding)) { diff --git a/src/Libraries/SmartStore.Services/Tasks/TaskScheduler.cs b/src/Libraries/SmartStore.Services/Tasks/TaskScheduler.cs index 22cecb7046..50b4df021b 100644 --- a/src/Libraries/SmartStore.Services/Tasks/TaskScheduler.cs +++ b/src/Libraries/SmartStore.Services/Tasks/TaskScheduler.cs @@ -173,8 +173,15 @@ protected internal virtual void CallEndpoint(string url) } else { + var response = t.Result; + + using (var logger = new TraceLogger()) + { + logger.Debug("TaskScheduler Sweep called successfully: {0}".FormatCurrent(response.GetResponseStream().AsString())); + } + _errCount = 0; - t.Result.Dispose(); + response.Dispose(); } }); } diff --git a/src/Presentation/SmartStore.Web/Controllers/TaskSchedulerController.cs b/src/Presentation/SmartStore.Web/Controllers/TaskSchedulerController.cs index 9b7b6763c2..860da5fa85 100644 --- a/src/Presentation/SmartStore.Web/Controllers/TaskSchedulerController.cs +++ b/src/Presentation/SmartStore.Web/Controllers/TaskSchedulerController.cs @@ -65,7 +65,7 @@ public ActionResult Sweep() } } - return Content("{0} tasks executed".FormatInvariant(count)); + return Content("{0} of {1} pending tasks executed".FormatInvariant(count, pendingTasks.Count)); } [HttpPost] From d401828451b56e35817f1b01770bf533cf9d0e1c Mon Sep 17 00:00:00 2001 From: Michael Herzog Date: Fri, 8 Jan 2016 14:30:31 +0100 Subject: [PATCH 140/626] Performance: eliminated sending of the whole product model to data grid via json response in several locations --- .../Controllers/CategoryController.cs | 9 ++- .../Controllers/ManufacturerController.cs | 9 ++- .../Controllers/ProductController.cs | 64 +++++++++++++++++-- 3 files changed, 73 insertions(+), 9 deletions(-) diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/CategoryController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/CategoryController.cs index a1b8d695d6..245cce40b5 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/CategoryController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/CategoryController.cs @@ -911,7 +911,14 @@ public ActionResult ProductAddPopupList(GridCommand command, CategoryModel.AddCa gridModel.Data = products.Select(x => { - var productModel = x.ToModel(); + var productModel = new ProductModel + { + Sku = x.Sku, + Published = x.Published, + ProductTypeLabelHint = x.ProductTypeLabelHint, + Name = x.Name, + Id = x.Id + }; productModel.ProductTypeName = x.GetProductTypeLabel(_localizationService); return productModel; diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/ManufacturerController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/ManufacturerController.cs index 2e7460bff4..51f74261f5 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/ManufacturerController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/ManufacturerController.cs @@ -596,7 +596,14 @@ public ActionResult ProductAddPopupList(GridCommand command, ManufacturerModel.A gridModel.Data = products.Select(x => { - var productModel = x.ToModel(); + var productModel = new ProductModel + { + Sku = x.Sku, + Published = x.Published, + ProductTypeLabelHint = x.ProductTypeLabelHint, + Name = x.Name, + Id = x.Id + }; productModel.ProductTypeName = x.GetProductTypeLabel(_localizationService); return productModel; diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/ProductController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/ProductController.cs index 09139d349c..bb8c302ba9 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/ProductController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/ProductController.cs @@ -943,8 +943,18 @@ public ActionResult ProductList(GridCommand command, ProductListModel model) gridModel.Data = products.Select(x => { - var productModel = x.ToModel(); - productModel.FullDescription = ""; // Perf + var productModel = new ProductModel + { + Sku = x.Sku, + Published = x.Published, + ProductTypeLabelHint = x.ProductTypeLabelHint, + Name = x.Name, + Id = x.Id, + StockQuantity = x.StockQuantity, + Price = x.Price, + LimitedToStores = x.LimitedToStores + }; + PrepareProductPictureThumbnailModel(productModel, x); productModel.ProductTypeName = x.GetProductTypeLabel(_localizationService); @@ -1654,7 +1664,15 @@ public ActionResult RelatedProductAddPopupList(GridCommand command, ProductModel gridModel.Data = products.Select(x => { - var productModel = x.ToModel(); + var productModel = new ProductModel + { + Sku = x.Sku, + Published = x.Published, + ProductTypeLabelHint = x.ProductTypeLabelHint, + Name = x.Name, + Id = x.Id + }; + productModel.ProductTypeName = x.GetProductTypeLabel(_localizationService); return productModel; @@ -1876,7 +1894,15 @@ public ActionResult CrossSellProductAddPopupList(GridCommand command, ProductMod gridModel.Data = products.Select(x => { - var productModel = x.ToModel(); + var productModel = new ProductModel + { + Sku = x.Sku, + Published = x.Published, + ProductTypeLabelHint = x.ProductTypeLabelHint, + Name = x.Name, + Id = x.Id + }; + productModel.ProductTypeName = x.GetProductTypeLabel(_localizationService); return productModel; @@ -2095,7 +2121,15 @@ public ActionResult AssociatedProductAddPopupList(GridCommand command, ProductMo gridModel.Data = products.Select(x => { - var productModel = x.ToModel(); + var productModel = new ProductModel + { + Sku = x.Sku, + Published = x.Published, + ProductTypeLabelHint = x.ProductTypeLabelHint, + Name = x.Name, + Id = x.Id + }; + productModel.ProductTypeName = x.GetProductTypeLabel(_localizationService); return productModel; @@ -2411,7 +2445,15 @@ public ActionResult BundleItemAddPopupList(GridCommand command, ProductModel.Add gridModel.Data = products.Select(x => { - var productModel = x.ToModel(); + var productModel = new ProductModel + { + Sku = x.Sku, + Published = x.Published, + ProductTypeLabelHint = x.ProductTypeLabelHint, + Name = x.Name, + Id = x.Id + }; + productModel.ProductTypeName = x.GetProductTypeLabel(_localizationService); productModel.ProductSelectCheckboxClass = (!x.CanBeBundleItem() ? " hide" : ""); @@ -3611,7 +3653,15 @@ public ActionResult ProductAttributeValueLinkagePopupList(GridCommand command, P gridModel.Data = products.Select(x => { - var productModel = x.ToModel(); + var productModel = new ProductModel + { + Sku = x.Sku, + Published = x.Published, + ProductTypeLabelHint = x.ProductTypeLabelHint, + Name = x.Name, + Id = x.Id + }; + productModel.ProductTypeName = x.GetProductTypeLabel(_localizationService); return productModel; From 6530f97a5ab382a831c056d9f02ed8176bfd9429 Mon Sep 17 00:00:00 2001 From: Murat Cakir Date: Fri, 8 Jan 2016 19:38:35 +0100 Subject: [PATCH 141/626] Removed TaskScheduler sweep logging --- .../SmartStore.Services/Tasks/TaskScheduler.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Libraries/SmartStore.Services/Tasks/TaskScheduler.cs b/src/Libraries/SmartStore.Services/Tasks/TaskScheduler.cs index 50b4df021b..8cb0fbc0d7 100644 --- a/src/Libraries/SmartStore.Services/Tasks/TaskScheduler.cs +++ b/src/Libraries/SmartStore.Services/Tasks/TaskScheduler.cs @@ -173,14 +173,14 @@ protected internal virtual void CallEndpoint(string url) } else { + _errCount = 0; var response = t.Result; - using (var logger = new TraceLogger()) - { - logger.Debug("TaskScheduler Sweep called successfully: {0}".FormatCurrent(response.GetResponseStream().AsString())); - } + //using (var logger = new TraceLogger()) + //{ + // logger.Debug("TaskScheduler Sweep called successfully: {0}".FormatCurrent(response.GetResponseStream().AsString())); + //} - _errCount = 0; response.Dispose(); } }); From 94cc64cd43133ea5f0a0d36b25d2d53181369d7b Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Sat, 9 Jan 2016 12:55:50 +0100 Subject: [PATCH 142/626] Resolves #760 Setting to set a customer role for new registered users --- changelog.md | 1 + .../Domain/Customers/CustomerSettings.cs | 9 +- .../201512151526290_ImportFramework.cs | 22 +++ .../Customers/CustomerRegistrationService.cs | 148 +++++++++--------- .../Controllers/SettingController.cs | 26 +-- .../Settings/CustomerUserSettingsModel.cs | 10 +- .../Views/Setting/CustomerUser.cshtml | 11 +- .../CustomerRegistrationServiceTests.cs | 6 +- 8 files changed, 141 insertions(+), 92 deletions(-) diff --git a/changelog.md b/changelog.md index f6fa16e556..6a82d8e636 100644 --- a/changelog.md +++ b/changelog.md @@ -33,6 +33,7 @@ * #841 Activity log for deleting an order * More settings to control creation of SEO names * GMC feed: Supporting fields multipack, bundle, adult, energy efficiency class and custom label (0 to 4) +* #760 Setting to set a customer role for new registered users ### Improvements * (Perf) Implemented static caches for URL aliases and localized properties. Increases app startup and request speed by up to 30%. diff --git a/src/Libraries/SmartStore.Core/Domain/Customers/CustomerSettings.cs b/src/Libraries/SmartStore.Core/Domain/Customers/CustomerSettings.cs index 83380a63a3..d0dbf678e5 100644 --- a/src/Libraries/SmartStore.Core/Domain/Customers/CustomerSettings.cs +++ b/src/Libraries/SmartStore.Core/Domain/Customers/CustomerSettings.cs @@ -151,7 +151,6 @@ public CustomerSettings() /// public bool StoreLastVisitedPage { get; set; } - #region Form fields /// @@ -246,8 +245,12 @@ public CustomerSettings() #endregion - // codehint: sm-add (no ui, only db edit) public string PrefillLoginUsername { get; set; } public string PrefillLoginPwd { get; set; } - } + + /// + /// Identifier of a customer role that new registered customers will be assigned to + /// + public int RegisterCustomerRoleId { get; set; } + } } \ No newline at end of file diff --git a/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs b/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs index 7f2dec3086..2699566e17 100644 --- a/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs +++ b/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs @@ -316,6 +316,28 @@ public void MigrateLocaleResources(LocaleResourcesBuilder builder) builder.AddOrUpdate("Admin.System.Warnings.DigitsOnly", "Please enter digits only.", "Bitte nur Ziffern eingeben."); + + builder.AddOrUpdate("Account.Register.Errors.CannotRegisterSearchEngine", + "A search engine can't be registered.", + "Eine Suchmaschine kann nicht registriert werden."); + + builder.AddOrUpdate("Account.Register.Errors.CannotRegisterTaskAccount", + "A background task account can't be registered.", + "Das Konto einer geplanten Aufgabe kann nicht registriert werden."); + + builder.AddOrUpdate("Account.Register.Errors.AlreadyRegistered", + "The customer is already registered.", + "Der Kunde ist bereits registriert."); + + builder.AddOrUpdate("Admin.Customers.CustomerRoles.CannotFoundRole", + "The customer role \"{0}\" cannot be found.", + "Die Kundengruppe \"{0}\" wurde nicht gefunden."); + + builder.AddOrUpdate("Admin.Configuration.Settings.CustomerUser.RegisterCustomerRole", + "Customer role at registrations", + "Kundengruppe bei Registrierungen", + "Specifies a customer role that will be assigned to newly registered customers.", + "Legt eine Kundengruppe fest, die neu registrierten Kunden zugeordnet wird."); } } } diff --git a/src/Libraries/SmartStore.Services/Customers/CustomerRegistrationService.cs b/src/Libraries/SmartStore.Services/Customers/CustomerRegistrationService.cs index 1615a2ce96..49fb4587aa 100644 --- a/src/Libraries/SmartStore.Services/Customers/CustomerRegistrationService.cs +++ b/src/Libraries/SmartStore.Services/Customers/CustomerRegistrationService.cs @@ -3,23 +3,22 @@ using SmartStore.Core; using SmartStore.Core.Domain.Customers; using SmartStore.Core.Events; -using SmartStore.Services.Localization; +using SmartStore.Core.Localization; using SmartStore.Services.Messages; using SmartStore.Services.Security; namespace SmartStore.Services.Customers { - /// - /// Customer registration service - /// - public partial class CustomerRegistrationService : ICustomerRegistrationService + /// + /// Customer registration service + /// + public partial class CustomerRegistrationService : ICustomerRegistrationService { #region Fields private readonly ICustomerService _customerService; private readonly IEncryptionService _encryptionService; private readonly INewsLetterSubscriptionService _newsLetterSubscriptionService; - private readonly ILocalizationService _localizationService; private readonly RewardPointsSettings _rewardPointsSettings; private readonly CustomerSettings _customerSettings; private readonly IStoreContext _storeContext; @@ -35,31 +34,33 @@ public partial class CustomerRegistrationService : ICustomerRegistrationService public CustomerRegistrationService(ICustomerService customerService, IEncryptionService encryptionService, INewsLetterSubscriptionService newsLetterSubscriptionService, - ILocalizationService localizationService, RewardPointsSettings rewardPointsSettings, CustomerSettings customerSettings, IStoreContext storeContext, IEventPublisher eventPublisher) { this._customerService = customerService; this._encryptionService = encryptionService; this._newsLetterSubscriptionService = newsLetterSubscriptionService; - this._localizationService = localizationService; this._rewardPointsSettings = rewardPointsSettings; this._customerSettings = customerSettings; this._storeContext = storeContext; this._eventPublisher = eventPublisher; - } - #endregion + T = NullLocalizer.Instance; + } - #region Methods + #endregion - /// - /// Validate customer - /// - /// Username or email - /// Password - /// Result - public virtual bool ValidateCustomer(string usernameOrEmail, string password) + public Localizer T { get; set; } + + #region Methods + + /// + /// Validate customer + /// + /// Username or email + /// Password + /// Result + public virtual bool ValidateCustomer(string usernameOrEmail, string password) { Customer customer = null; if (_customerSettings.UsernamesEnabled) @@ -112,48 +113,46 @@ public virtual bool ValidateCustomer(string usernameOrEmail, string password) /// Result public virtual CustomerRegistrationResult RegisterCustomer(CustomerRegistrationRequest request) { - if (request == null) - throw new ArgumentNullException("request"); - - if (request.Customer == null) - throw new ArgumentException("Can't load current customer"); + Guard.ArgumentNotNull(() => request); + Guard.ArgumentNotNull(() => request.Customer); var result = new CustomerRegistrationResult(); + if (request.Customer.IsSearchEngineAccount()) { - result.AddError("Search engine can't be registered"); + result.AddError(T("Account.Register.Errors.CannotRegisterSearchEngine")); return result; } if (request.Customer.IsBackgroundTaskAccount()) { - result.AddError("Background task account can't be registered"); + result.AddError(T("Account.Register.Errors.CannotRegisterTaskAccount")); return result; } if (request.Customer.IsRegistered()) { - result.AddError("Current customer is already registered"); + result.AddError(T("Account.Register.Errors.AlreadyRegistered")); return result; } if (String.IsNullOrEmpty(request.Email)) { - result.AddError(_localizationService.GetResource("Account.Register.Errors.EmailIsNotProvided")); + result.AddError(T("Account.Register.Errors.EmailIsNotProvided")); return result; } if (!request.Email.IsEmail()) { - result.AddError(_localizationService.GetResource("Common.WrongEmail")); + result.AddError(T("Common.WrongEmail")); return result; } if (String.IsNullOrWhiteSpace(request.Password)) { - result.AddError(_localizationService.GetResource("Account.Register.Errors.PasswordIsNotProvided")); + result.AddError(T("Account.Register.Errors.PasswordIsNotProvided")); return result; } if (_customerSettings.UsernamesEnabled) { if (String.IsNullOrEmpty(request.Username)) { - result.AddError(_localizationService.GetResource("Account.Register.Errors.UsernameIsNotProvided")); + result.AddError(T("Account.Register.Errors.UsernameIsNotProvided")); return result; } } @@ -161,14 +160,14 @@ public virtual CustomerRegistrationResult RegisterCustomer(CustomerRegistrationR //validate unique user if (_customerService.GetCustomerByEmail(request.Email) != null) { - result.AddError(_localizationService.GetResource("Account.Register.Errors.EmailAlreadyExists")); + result.AddError(T("Account.Register.Errors.EmailAlreadyExists")); return result; } if (_customerSettings.UsernamesEnabled) { if (_customerService.GetCustomerByUsername(request.Username) != null) { - result.AddError(_localizationService.GetResource("Account.Register.Errors.UsernameAlreadyExists")); + result.AddError(T("Account.Register.Errors.UsernameAlreadyExists")); return result; } } @@ -180,45 +179,52 @@ public virtual CustomerRegistrationResult RegisterCustomer(CustomerRegistrationR switch (request.PasswordFormat) { - case PasswordFormat.Clear: - { - request.Customer.Password = request.Password; - } - break; - case PasswordFormat.Encrypted: - { - request.Customer.Password = _encryptionService.EncryptText(request.Password); - } - break; - case PasswordFormat.Hashed: - { - string saltKey = _encryptionService.CreateSaltKey(5); - request.Customer.PasswordSalt = saltKey; - request.Customer.Password = _encryptionService.CreatePasswordHash(request.Password, saltKey, _customerSettings.HashedPasswordFormat); - } - break; - default: - break; + case PasswordFormat.Clear: + request.Customer.Password = request.Password; + break; + case PasswordFormat.Encrypted: + request.Customer.Password = _encryptionService.EncryptText(request.Password); + break; + case PasswordFormat.Hashed: + string saltKey = _encryptionService.CreateSaltKey(5); + request.Customer.PasswordSalt = saltKey; + request.Customer.Password = _encryptionService.CreatePasswordHash(request.Password, saltKey, _customerSettings.HashedPasswordFormat); + break; } request.Customer.Active = request.IsApproved; - - //add to 'Registered' role - var registeredRole = _customerService.GetCustomerRoleBySystemName(SystemCustomerRoleNames.Registered); - if (registeredRole == null) - throw new SmartException("'Registered' role could not be loaded"); + + if (_customerSettings.RegisterCustomerRoleId != 0) + { + var customerRole = _customerService.GetCustomerRoleById(_customerSettings.RegisterCustomerRoleId); + request.Customer.CustomerRoles.Add(customerRole); + } + + //add to 'Registered' role + var registeredRole = _customerService.GetCustomerRoleBySystemName(SystemCustomerRoleNames.Registered); + if (registeredRole == null) + { + throw new SmartException(T("Admin.Customers.CustomerRoles.CannotFoundRole", "Registered")); + } + request.Customer.CustomerRoles.Add(registeredRole); + //remove from 'Guests' role var guestRole = request.Customer.CustomerRoles.FirstOrDefault(cr => cr.SystemName == SystemCustomerRoleNames.Guests); - if (guestRole != null) - request.Customer.CustomerRoles.Remove(guestRole); + if (guestRole != null) + { + request.Customer.CustomerRoles.Remove(guestRole); + } - //Add reward points for customer registration (if enabled) - if (_rewardPointsSettings.Enabled && _rewardPointsSettings.PointsForRegistration > 0) - request.Customer.AddRewardPointsHistoryEntry(_rewardPointsSettings.PointsForRegistration, _localizationService.GetResource("RewardPoints.Message.RegisteredAsCustomer")); + //Add reward points for customer registration (if enabled) + if (_rewardPointsSettings.Enabled && _rewardPointsSettings.PointsForRegistration > 0) + { + request.Customer.AddRewardPointsHistoryEntry(_rewardPointsSettings.PointsForRegistration, T("RewardPoints.Message.RegisteredAsCustomer")); + } _customerService.UpdateCustomer(request.Customer); - _eventPublisher.Publish(new CustomerRegisteredEvent{ Customer = request.Customer }); + _eventPublisher.Publish(new CustomerRegisteredEvent { Customer = request.Customer }); + return result; } @@ -235,19 +241,19 @@ public virtual PasswordChangeResult ChangePassword(ChangePasswordRequest request var result = new PasswordChangeResult(); if (String.IsNullOrWhiteSpace(request.Email)) { - result.AddError(_localizationService.GetResource("Account.ChangePassword.Errors.EmailIsNotProvided")); + result.AddError(T("Account.ChangePassword.Errors.EmailIsNotProvided")); return result; } if (String.IsNullOrWhiteSpace(request.NewPassword)) { - result.AddError(_localizationService.GetResource("Account.ChangePassword.Errors.PasswordIsNotProvided")); + result.AddError(T("Account.ChangePassword.Errors.PasswordIsNotProvided")); return result; } var customer = _customerService.GetCustomerByEmail(request.Email); if (customer == null) { - result.AddError(_localizationService.GetResource("Account.ChangePassword.Errors.EmailNotFound")); + result.AddError(T("Account.ChangePassword.Errors.EmailNotFound")); return result; } @@ -272,7 +278,7 @@ public virtual PasswordChangeResult ChangePassword(ChangePasswordRequest request bool oldPasswordIsValid = oldPwd == customer.Password; if (!oldPasswordIsValid) - result.AddError(_localizationService.GetResource("Account.ChangePassword.Errors.OldPasswordDoesntMatch")); + result.AddError(T("Account.ChangePassword.Errors.OldPasswordDoesntMatch")); if (oldPasswordIsValid) requestIsValid = true; @@ -327,14 +333,14 @@ public virtual void SetEmail(Customer customer, string newEmail) string oldEmail = customer.Email; if (!newEmail.IsEmail()) - throw new SmartException(_localizationService.GetResource("Account.EmailUsernameErrors.NewEmailIsNotValid")); + throw new SmartException(T("Account.EmailUsernameErrors.NewEmailIsNotValid")); if (newEmail.Length > 100) - throw new SmartException(_localizationService.GetResource("Account.EmailUsernameErrors.EmailTooLong")); + throw new SmartException(T("Account.EmailUsernameErrors.EmailTooLong")); var customer2 = _customerService.GetCustomerByEmail(newEmail); if (customer2 != null && customer.Id != customer2.Id) - throw new SmartException(_localizationService.GetResource("Account.EmailUsernameErrors.EmailAlreadyExists")); + throw new SmartException(T("Account.EmailUsernameErrors.EmailAlreadyExists")); customer.Email = newEmail; _customerService.UpdateCustomer(customer); @@ -370,11 +376,11 @@ public virtual void SetUsername(Customer customer, string newUsername) newUsername = newUsername.Trim(); if (newUsername.Length > 100) - throw new SmartException(_localizationService.GetResource("Account.EmailUsernameErrors.UsernameTooLong")); + throw new SmartException(T("Account.EmailUsernameErrors.UsernameTooLong")); var user2 = _customerService.GetCustomerByUsername(newUsername); if (user2 != null && customer.Id != user2.Id) - throw new SmartException(_localizationService.GetResource("Account.EmailUsernameErrors.UsernameAlreadyExists")); + throw new SmartException(T("Account.EmailUsernameErrors.UsernameAlreadyExists")); customer.Username = newUsername; _customerService.UpdateCustomer(customer); diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/SettingController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/SettingController.cs index 85ea07067b..47df2024dc 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/SettingController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/SettingController.cs @@ -902,13 +902,15 @@ public ActionResult CustomerUser() var storeScope = this.GetActiveStoreScopeConfiguration(_services.StoreService, _services.WorkContext); StoreDependingSettings.CreateViewDataObject(storeScope); + var allCustomerRoles = _customerService.GetAllCustomerRoles(true); + var customerSettings = _services.Settings.LoadSetting(storeScope); var addressSettings = _services.Settings.LoadSetting(storeScope); var dateTimeSettings = _services.Settings.LoadSetting(storeScope); var externalAuthenticationSettings = _services.Settings.LoadSetting(storeScope); - //merge settings - var model = new CustomerUserSettingsModel(); + //merge settings + var model = new CustomerUserSettingsModel(); model.CustomerSettings = customerSettings.ToModel(); StoreDependingSettings.GetOverrideKeys(customerSettings, model.CustomerSettings, storeScope, _services.Settings, false); @@ -919,14 +921,15 @@ public ActionResult CustomerUser() model.DateTimeSettings.AllowCustomersToSetTimeZone = dateTimeSettings.AllowCustomersToSetTimeZone; model.DateTimeSettings.DefaultStoreTimeZoneId = _dateTimeHelper.DefaultStoreTimeZone.Id; + foreach (TimeZoneInfo timeZone in _dateTimeHelper.GetSystemTimeZones()) { - model.DateTimeSettings.AvailableTimeZones.Add(new SelectListItem() - { - Text = timeZone.DisplayName, - Value = timeZone.Id, - Selected = timeZone.Id.Equals(_dateTimeHelper.DefaultStoreTimeZone.Id, StringComparison.InvariantCultureIgnoreCase) - }); + model.DateTimeSettings.AvailableTimeZones.Add(new SelectListItem + { + Text = timeZone.DisplayName, + Value = timeZone.Id, + Selected = timeZone.Id.Equals(_dateTimeHelper.DefaultStoreTimeZone.Id, StringComparison.InvariantCultureIgnoreCase) + }); } StoreDependingSettings.GetOverrideKeys(dateTimeSettings, model.DateTimeSettings, storeScope, _services.Settings, false); @@ -938,7 +941,12 @@ public ActionResult CustomerUser() model.CustomerSettings.AvailableCustomerNumberMethods = customerSettings.CustomerNumberMethod.ToSelectList(); model.CustomerSettings.AvailableCustomerNumberVisibilities = customerSettings.CustomerNumberVisibility.ToSelectList(); - return View(model); + model.CustomerSettings.AvailableRegisterCustomerRoles = allCustomerRoles + .Where(x => x.SystemName != SystemCustomerRoleNames.Registered && x.SystemName != SystemCustomerRoleNames.Guests) + .Select(x => new SelectListItem { Text = x.Name, Value = x.Id.ToString() }) + .ToList(); + + return View(model); } [HttpPost] diff --git a/src/Presentation/SmartStore.Web/Administration/Models/Settings/CustomerUserSettingsModel.cs b/src/Presentation/SmartStore.Web/Administration/Models/Settings/CustomerUserSettingsModel.cs index 1ad5872150..2e076d6471 100644 --- a/src/Presentation/SmartStore.Web/Administration/Models/Settings/CustomerUserSettingsModel.cs +++ b/src/Presentation/SmartStore.Web/Administration/Models/Settings/CustomerUserSettingsModel.cs @@ -29,8 +29,9 @@ public partial class CustomerSettingsModel [SmartResourceDisplayName("Admin.Configuration.Settings.Catalog.DefaultSortOrderMode")] public CustomerNumberMethod CustomerNumberMethod { get; set; } public SelectList AvailableCustomerNumberMethods { get; set; } + public IList AvailableRegisterCustomerRoles { get; set; } - [SmartResourceDisplayName("Admin.Configuration.Settings.Catalog.DefaultSortOrderMode")] + [SmartResourceDisplayName("Admin.Configuration.Settings.Catalog.DefaultSortOrderMode")] public CustomerNumberVisibility CustomerNumberVisibility { get; set; } public SelectList AvailableCustomerNumberVisibilities { get; set; } @@ -43,7 +44,10 @@ public partial class CustomerSettingsModel [SmartResourceDisplayName("Admin.Configuration.Settings.CustomerUser.UserRegistrationType")] public int UserRegistrationType { get; set; } - [SmartResourceDisplayName("Admin.Configuration.Settings.CustomerUser.AllowCustomersToUploadAvatars")] + [SmartResourceDisplayName("Admin.Configuration.Settings.CustomerUser.RegisterCustomerRole")] + public int RegisterCustomerRoleId { get; set; } + + [SmartResourceDisplayName("Admin.Configuration.Settings.CustomerUser.AllowCustomersToUploadAvatars")] public bool AllowCustomersToUploadAvatars { get; set; } [SmartResourceDisplayName("Admin.Configuration.Settings.CustomerUser.DefaultAvatarEnabled")] @@ -131,7 +135,7 @@ public partial class CustomerSettingsModel public bool FaxEnabled { get; set; } [SmartResourceDisplayName("Admin.Configuration.Settings.CustomerUser.FaxRequired")] public bool FaxRequired { get; set; } - } + } public partial class AddressSettingsModel { diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Setting/CustomerUser.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Setting/CustomerUser.cshtml index b22985819c..d3c493aad1 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Setting/CustomerUser.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Setting/CustomerUser.cshtml @@ -3,7 +3,6 @@ @using SmartStore.Core.Domain.Customers; @using SmartStore.Core.Domain.Security; @{ - //page title ViewBag.Title = T("Admin.Configuration.Settings.CustomerUser").Text; } @using (Html.BeginForm()) @@ -128,6 +127,16 @@ @Html.ValidationMessageFor(model => model.CustomerSettings.UserRegistrationType)
+ @Html.SmartLabelFor(model => model.CustomerSettings.RegisterCustomerRoleId) + + @Html.SettingOverrideCheckbox(model => Model.CustomerSettings.RegisterCustomerRoleId) + @Html.DropDownListFor(model => model.CustomerSettings.RegisterCustomerRoleId, Model.CustomerSettings.AvailableRegisterCustomerRoles, T("Common.Unspecified")) + @Html.ValidationMessageFor(model => model.CustomerSettings.RegisterCustomerRoleId) +
@Html.SmartLabelFor(model => model.CustomerSettings.AllowCustomersToUploadAvatars) diff --git a/src/Tests/SmartStore.Services.Tests/Customers/CustomerRegistrationServiceTests.cs b/src/Tests/SmartStore.Services.Tests/Customers/CustomerRegistrationServiceTests.cs index b356946e7c..990c27b02f 100644 --- a/src/Tests/SmartStore.Services.Tests/Customers/CustomerRegistrationServiceTests.cs +++ b/src/Tests/SmartStore.Services.Tests/Customers/CustomerRegistrationServiceTests.cs @@ -11,7 +11,6 @@ using SmartStore.Core.Events; using SmartStore.Services.Common; using SmartStore.Services.Customers; -using SmartStore.Services.Localization; using SmartStore.Services.Messages; using SmartStore.Services.Security; using SmartStore.Tests; @@ -29,7 +28,6 @@ public class CustomerRegistrationServiceTests : ServiceTest IEncryptionService _encryptionService; ICustomerService _customerService; ICustomerRegistrationService _customerRegistrationService; - ILocalizationService _localizationService; CustomerSettings _customerSettings; INewsLetterSubscriptionService _newsLetterSubscriptionService; IEventPublisher _eventPublisher; @@ -117,15 +115,13 @@ public class CustomerRegistrationServiceTests : ServiceTest _genericAttributeService = MockRepository.GenerateMock(); _newsLetterSubscriptionService = MockRepository.GenerateMock(); - _localizationService = MockRepository.GenerateMock(); _storeContext = MockRepository.GenerateMock(); _customerService = new CustomerService(new NullCache(), _customerRepo, _customerRoleRepo, _genericAttributeRepo, _rewardPointsHistoryRepo, _genericAttributeService, _eventPublisher, _rewardPointsSettings); _customerRegistrationService = new CustomerRegistrationService(_customerService, - _encryptionService, _newsLetterSubscriptionService, _localizationService, - _rewardPointsSettings, _customerSettings, _storeContext, _eventPublisher); + _encryptionService, _newsLetterSubscriptionService, _rewardPointsSettings, _customerSettings, _storeContext, _eventPublisher); } //[Test] From 019a4d24f9f72f7f45cfb798b19b102e30017efe Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Sun, 10 Jan 2016 11:49:19 +0100 Subject: [PATCH 143/626] Resolves #800 Multi-store: Option to display all orders of all stores for customer in frontend --- changelog.md | 1 + .../Domain/Orders/OrderSettings.cs | 6 +++- .../201512151526290_ImportFramework.cs | 9 ++++++ .../Controllers/SettingController.cs | 5 ++- .../Infrastructure/AutoMapperStartupTask.cs | 1 + .../Models/Settings/OrderSettingsModel.cs | 4 +++ .../Administration/Views/Setting/Order.cshtml | 12 +++++++ .../Controllers/CustomerController.cs | 31 ++++++++++++------- 8 files changed, 55 insertions(+), 14 deletions(-) diff --git a/changelog.md b/changelog.md index 6a82d8e636..519c0f8906 100644 --- a/changelog.md +++ b/changelog.md @@ -34,6 +34,7 @@ * More settings to control creation of SEO names * GMC feed: Supporting fields multipack, bundle, adult, energy efficiency class and custom label (0 to 4) * #760 Setting to set a customer role for new registered users +* #800 Multi-store: Option to display all orders of all stores for customer in frontend ### Improvements * (Perf) Implemented static caches for URL aliases and localized properties. Increases app startup and request speed by up to 30%. diff --git a/src/Libraries/SmartStore.Core/Domain/Orders/OrderSettings.cs b/src/Libraries/SmartStore.Core/Domain/Orders/OrderSettings.cs index 7a55c36f70..996271de79 100644 --- a/src/Libraries/SmartStore.Core/Domain/Orders/OrderSettings.cs +++ b/src/Libraries/SmartStore.Core/Domain/Orders/OrderSettings.cs @@ -83,5 +83,9 @@ public OrderSettings() /// public int MinimumOrderPlacementInterval { get; set; } - } + /// + /// Gets or sets a value indicating whether to display all orders of all stores to a customer + /// + public bool DisplayOrdersOfAllStores { get; set; } + } } \ No newline at end of file diff --git a/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs b/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs index 2699566e17..767af5b90c 100644 --- a/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs +++ b/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs @@ -338,6 +338,15 @@ public void MigrateLocaleResources(LocaleResourcesBuilder builder) "Kundengruppe bei Registrierungen", "Specifies a customer role that will be assigned to newly registered customers.", "Legt eine Kundengruppe fest, die neu registrierten Kunden zugeordnet wird."); + + builder.AddOrUpdate("Admin.Configuration.Settings.Order.DisplayOrdersOfAllStores", + "Display orders of all stores", + "Auftrge aller Shops anzeigen", + "Specifies whether to display the orders of all stores to the customer. If this option is disabled, only the orders of the current store are displayed.", + "Legt fest, ob dem Kunden die Auftrge aller Shops angezeigt werden sollen. Ist diese Option deaktiviert, so werden nur die Auftrge des aktuellen Shops angezeigt."); + + builder.AddOrUpdate("Admin.Configuration.Settings.Order.GiftCards_Deactivated") + .Value("de", "Geschenkgutschein wird deaktiviert, wenn Auftragsstatus..."); } } } diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/SettingController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/SettingController.cs index 47df2024dc..1d9becf2f3 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/SettingController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/SettingController.cs @@ -685,13 +685,16 @@ public ActionResult Order() //load settings for a chosen store scope var storeScope = this.GetActiveStoreScopeConfiguration(_services.StoreService, _services.WorkContext); var orderSettings = _services.Settings.LoadSetting(storeScope); - var store = (storeScope == 0 ? _services.StoreContext.CurrentStore : _services.StoreService.GetStoreById(storeScope)); + + var allStores = _services.StoreService.GetAllStores(); + var store = (storeScope == 0 ? _services.StoreContext.CurrentStore : allStores.FirstOrDefault(x => x.Id == storeScope)); var model = orderSettings.ToModel(); StoreDependingSettings.GetOverrideKeys(orderSettings, model, storeScope, _services.Settings); model.PrimaryStoreCurrencyCode = store.PrimaryStoreCurrency.CurrencyCode; + model.StoreCount = allStores.Count; //gift card activation/deactivation model.GiftCards_Activated_OrderStatuses = OrderStatus.Pending.ToSelectList(false).ToList(); diff --git a/src/Presentation/SmartStore.Web/Administration/Infrastructure/AutoMapperStartupTask.cs b/src/Presentation/SmartStore.Web/Administration/Infrastructure/AutoMapperStartupTask.cs index 9c6a24d877..3cbb5afe21 100644 --- a/src/Presentation/SmartStore.Web/Administration/Infrastructure/AutoMapperStartupTask.cs +++ b/src/Presentation/SmartStore.Web/Administration/Infrastructure/AutoMapperStartupTask.cs @@ -640,6 +640,7 @@ public void Execute() .ForMember(dest => dest.GiftCards_Activated_OrderStatuses, mo => mo.Ignore()) .ForMember(dest => dest.GiftCards_Deactivated_OrderStatuses, mo => mo.Ignore()) .ForMember(dest => dest.PrimaryStoreCurrencyCode, mo => mo.Ignore()) + .ForMember(dest => dest.StoreCount, mo => mo.Ignore()) .ForMember(dest => dest.OrderIdent, mo => mo.Ignore()) .ForMember(dest => dest.Locales, mo => mo.Ignore()); Mapper.CreateMap() diff --git a/src/Presentation/SmartStore.Web/Administration/Models/Settings/OrderSettingsModel.cs b/src/Presentation/SmartStore.Web/Administration/Models/Settings/OrderSettingsModel.cs index ea2bc65410..c54a264eb5 100644 --- a/src/Presentation/SmartStore.Web/Administration/Models/Settings/OrderSettingsModel.cs +++ b/src/Presentation/SmartStore.Web/Administration/Models/Settings/OrderSettingsModel.cs @@ -58,10 +58,14 @@ public OrderSettingsModel() public IList GiftCards_Deactivated_OrderStatuses { get; set; } public string PrimaryStoreCurrencyCode { get; set; } + public int StoreCount { get; set; } [SmartResourceDisplayName("Admin.Configuration.Settings.Order.OrderIdent")] public int? OrderIdent { get; set; } + [SmartResourceDisplayName("Admin.Configuration.Settings.Order.DisplayOrdersOfAllStores")] + public bool DisplayOrdersOfAllStores { get; set; } + public IList Locales { get; set; } } diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Setting/Order.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Setting/Order.cshtml index 3c29b263a1..df566da1ed 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Setting/Order.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Setting/Order.cshtml @@ -116,6 +116,18 @@
+ @Html.SmartLabelFor(model => model.DisplayOrdersOfAllStores) + + @Html.SettingEditorFor(model => model.DisplayOrdersOfAllStores) + @Html.ValidationMessageFor(model => model.DisplayOrdersOfAllStores) +
} diff --git a/src/Presentation/SmartStore.Web/Controllers/CustomerController.cs b/src/Presentation/SmartStore.Web/Controllers/CustomerController.cs index 1c9fa88791..e6b81ab62f 100644 --- a/src/Presentation/SmartStore.Web/Controllers/CustomerController.cs +++ b/src/Presentation/SmartStore.Web/Controllers/CustomerController.cs @@ -360,11 +360,14 @@ protected CustomerOrderListModel PrepareCustomerOrderListModel(Customer customer var model = new CustomerOrderListModel(); model.NavigationModel = GetCustomerNavigationModel(customer); model.NavigationModel.SelectedTab = CustomerNavigationEnum.Orders; - var orders = _orderService.SearchOrders(_storeContext.CurrentStore.Id, customer.Id, - null, null, null, null, null, null, null, null, 0, int.MaxValue); + + var storeScope = (_orderSettings.DisplayOrdersOfAllStores ? 0 : _storeContext.CurrentStore.Id); + + var orders = _orderService.SearchOrders(storeScope, customer.Id, null, null, null, null, null, null, null, null, 0, int.MaxValue); + foreach (var order in orders) { - var orderModel = new CustomerOrderListModel.OrderDetailsModel() + var orderModel = new CustomerOrderListModel.OrderDetailsModel { Id = order.Id, OrderNumber = order.GetOrderNumber(), @@ -372,6 +375,7 @@ protected CustomerOrderListModel PrepareCustomerOrderListModel(Customer customer OrderStatus = order.OrderStatus.GetLocalizedEnum(_localizationService, _workContext), IsReturnRequestAllowed = _orderProcessingService.IsReturnRequestAllowed(order) }; + var orderTotalInCustomerCurrency = _currencyService.ConvertCurrency(order.OrderTotal, order.CurrencyRate); orderModel.OrderTotal = _priceFormatter.FormatPrice(orderTotalInCustomerCurrency, true, order.CustomerCurrencyCode, false, _workContext.WorkingLanguage); @@ -382,7 +386,7 @@ protected CustomerOrderListModel PrepareCustomerOrderListModel(Customer customer foreach (var recurringPayment in recurringPayments) { - var recurringPaymentModel = new CustomerOrderListModel.RecurringOrderModel() + var recurringPaymentModel = new CustomerOrderListModel.RecurringOrderModel { Id = recurringPayment.Id, StartDate = _dateTimeHelper.ConvertToUserTime(recurringPayment.StartDateUtc, DateTimeKind.Utc).ToString(), @@ -1291,6 +1295,7 @@ public ActionResult Orders() var customer = _workContext.CurrentCustomer; var model = PrepareCustomerOrderListModel(customer); + return View(model); } @@ -1303,9 +1308,13 @@ public ActionResult CancelRecurringPayment(FormCollection form) //get recurring payment identifier int recurringPaymentId = 0; - foreach (var formValue in form.AllKeys) - if (formValue.StartsWith("cancelRecurringPayment", StringComparison.InvariantCultureIgnoreCase)) - recurringPaymentId = Convert.ToInt32(formValue.Substring("cancelRecurringPayment".Length)); + foreach (var formValue in form.AllKeys) + { + if (formValue.StartsWith("cancelRecurringPayment", StringComparison.InvariantCultureIgnoreCase)) + { + recurringPaymentId = Convert.ToInt32(formValue.Substring("cancelRecurringPayment".Length)); + } + } var recurringPayment = _orderService.GetRecurringPaymentById(recurringPaymentId); if (recurringPayment == null) @@ -1323,11 +1332,9 @@ public ActionResult CancelRecurringPayment(FormCollection form) return View(model); } - else - { - return RedirectToAction("Orders"); - } - } + + return RedirectToAction("Orders"); + } #endregion From 480cb8f4d23dd7e6379bf01eed349d47aadebabc Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Mon, 11 Jan 2016 13:29:59 +0100 Subject: [PATCH 144/626] Resolves #790 Improve language editing --- changelog.md | 1 + .../201512151526290_ImportFramework.cs | 10 + .../Administration/Content/admin.less | 15 ++ .../Controllers/LanguageController.cs | 195 +++++++++--------- .../Infrastructure/AutoMapperStartupTask.cs | 4 +- .../Models/Localization/LanguageModel.cs | 13 +- .../Localization/LanguageValidator.cs | 29 +-- .../Administration/Views/Language/List.cshtml | 7 +- .../Views/Language/_CreateOrUpdate.cshtml | 86 ++++---- 9 files changed, 205 insertions(+), 155 deletions(-) diff --git a/changelog.md b/changelog.md index 519c0f8906..f8dec5cd62 100644 --- a/changelog.md +++ b/changelog.md @@ -70,6 +70,7 @@ * Product grid sortable by name, price and created on * #26 Display company or name in order list * Added inline editing of country grid +* #790 Improved language editing ### Bugfixes * #523 Redirecting to payment provider performed by core instead of plugin diff --git a/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs b/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs index 767af5b90c..f281df8a32 100644 --- a/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs +++ b/src/Libraries/SmartStore.Data/Migrations/201512151526290_ImportFramework.cs @@ -347,6 +347,16 @@ public void MigrateLocaleResources(LocaleResourcesBuilder builder) builder.AddOrUpdate("Admin.Configuration.Settings.Order.GiftCards_Deactivated") .Value("de", "Geschenkgutschein wird deaktiviert, wenn Auftragsstatus..."); + + builder.AddOrUpdate("Admin.Configuration.Languages.Fields.UniqueSeoCode.Required", + "Please select a SEO language code.", + "Bitte legen Sie einen SEO Sprach-Code fest."); + + builder.AddOrUpdate("Admin.Configuration.Languages.Fields.FlagImageFileName", + "Flag image", + "Flaggenbild", + "Specifies the flag image. The files for the flag images must be stored in /Content/Images/flags/.", + "Legt das Flaggenbild fest. Die Dateien der Flaggenbilder mssen in /Content/Images/flags/ liegen."); } } } diff --git a/src/Presentation/SmartStore.Web/Administration/Content/admin.less b/src/Presentation/SmartStore.Web/Administration/Content/admin.less index eff6584861..26c3604e2a 100644 --- a/src/Presentation/SmartStore.Web/Administration/Content/admin.less +++ b/src/Presentation/SmartStore.Web/Administration/Content/admin.less @@ -432,6 +432,21 @@ td.adminData > input[type="checkbox"] { min-width: 314px; /* ensures more clean look & feel */ } +.select2-image-item { + img { + margin-bottom: 3px; + } + span:not(.select2-icon) { + padding-left: 5px; + } + .icon-container { + float: left; + display: inline-block; + width: 16px; + min-width: 16px; + max-width: 16px; + } +} /* select2 with large, templated items -------------------------------------------------------------- */ diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/LanguageController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/LanguageController.cs index 02587df34f..20824005a4 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/LanguageController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/LanguageController.cs @@ -1,15 +1,17 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Linq; using System.Web.Mvc; using SmartStore.Admin.Models.Localization; -using SmartStore.Core; using SmartStore.Core.Data; using SmartStore.Core.Domain.Common; using SmartStore.Core.Domain.DataExchange; using SmartStore.Core.Domain.Localization; using SmartStore.Core.Plugins; +using SmartStore.Services; +using SmartStore.Services.Directory; using SmartStore.Services.Localization; using SmartStore.Services.Security; using SmartStore.Services.Stores; @@ -28,74 +30,95 @@ public partial class LanguageController : AdminControllerBase #region Fields private readonly ILanguageService _languageService; - private readonly ILocalizationService _localizationService; - private readonly IStoreService _storeService; private readonly IStoreMappingService _storeMappingService; - private readonly IPermissionService _permissionService; - private readonly IWebHelper _webHelper; private readonly AdminAreaSettings _adminAreaSettings; private readonly IPluginFinder _pluginFinder; + private readonly ICountryService _countryService; + private readonly ICommonServices _services; #endregion #region Constructors public LanguageController(ILanguageService languageService, - ILocalizationService localizationService, - IStoreService storeService, IStoreMappingService storeMappingService, - IPermissionService permissionService, - IWebHelper webHelper, AdminAreaSettings adminAreaSettings, - IPluginFinder pluginFinder) + IPluginFinder pluginFinder, + ICountryService countryService, + ICommonServices services) { - this._localizationService = localizationService; this._languageService = languageService; - this._storeService = storeService; this._storeMappingService = storeMappingService; - this._permissionService = permissionService; - this._webHelper = webHelper; this._adminAreaSettings = adminAreaSettings; this._pluginFinder = pluginFinder; + this._countryService = countryService; + this._services = services; } - #endregion - + #endregion + #region Utilities - [NonAction] - private void PrepareFlagsModel(LanguageModel model) - { - if (model == null) - throw new ArgumentNullException("model"); + private void PrepareLanguageModel(LanguageModel model, Language language, bool excludeProperties) + { + var languageId = _services.WorkContext.WorkingLanguage.Id; - model.FlagFileNames = System.IO.Directory - .EnumerateFiles(_webHelper.MapPath("~/Content/Images/flags/"), "*.png", SearchOption.TopDirectoryOnly) - .Select(System.IO.Path.GetFileName) - .ToList(); - } + var allCultures = CultureInfo.GetCultures(CultureTypes.SpecificCultures) + .OrderBy(x => x.DisplayName) + .ToList(); - [NonAction] - private void PrepareStoresMappingModel(LanguageModel model, Language language, bool excludeProperties) - { - if (model == null) - throw new ArgumentNullException("model"); + var allCountryNames = _countryService.GetAllCountries(true) + .ToDictionary(x => x.TwoLetterIsoCode.EmptyNull().ToLower(), x => x.GetLocalized(y => y.Name, languageId, true, false)); - model.AvailableStores = _storeService - .GetAllStores() - .Select(s => s.ToModel()) + model.AvailableCultures = allCultures + .Select(x => new SelectListItem { Text = "{0} [{1}]".FormatInvariant(x.DisplayName, x.IetfLanguageTag), Value = x.IetfLanguageTag }) .ToList(); - if (!excludeProperties) + + model.AvailableTwoLetterLanguageCodes = new List(); + model.AvailableFlags = new List(); + + foreach (var item in allCultures) { - if (language != null) - { - model.SelectedStoreIds = _storeMappingService.GetStoresIdsWithAccess(language); - } - else + if (!model.AvailableTwoLetterLanguageCodes.Any(x => x.Value.IsCaseInsensitiveEqual(item.TwoLetterISOLanguageName))) { - model.SelectedStoreIds = new int[0]; + // display language name is not provided by net framework + var index = item.DisplayName.EmptyNull().IndexOf(" ("); + + if (index == -1) + index = item.DisplayName.EmptyNull().IndexOf(" ["); + + var displayName = "{0} [{1}]".FormatInvariant( + index == -1 ? item.DisplayName : item.DisplayName.Substring(0, index), + item.TwoLetterISOLanguageName); + + model.AvailableTwoLetterLanguageCodes.Add(new SelectListItem { Text = displayName, Value = item.TwoLetterISOLanguageName }); } } + + foreach (var path in Directory.EnumerateFiles(_services.WebHelper.MapPath("~/Content/Images/flags/"), "*.png", SearchOption.TopDirectoryOnly)) + { + var name = Path.GetFileNameWithoutExtension(path).EmptyNull().ToLower(); + string countryDescription = null; + + if (allCountryNames.ContainsKey(name)) + countryDescription = "{0} [{1}]".FormatInvariant(allCountryNames[name], name); + + if (countryDescription.IsEmpty()) + countryDescription = name; + + model.AvailableFlags.Add(new SelectListItem { Text = countryDescription, Value = Path.GetFileName(path) }); + } + + model.AvailableFlags = model.AvailableFlags.OrderBy(x => x.Text).ToList(); + + model.AvailableStores = _services.StoreService.GetAllStores() + .Select(s => s.ToModel()) + .ToList(); + + if (!excludeProperties) + { + model.SelectedStoreIds = _storeMappingService.GetStoresIdsWithAccess(language); + } } #endregion @@ -109,15 +132,17 @@ public ActionResult Index() public ActionResult List() { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageLanguages)) + if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageLanguages)) return AccessDeniedView(); var languages = _languageService.GetAllLanguages(true); + var gridModel = new GridModel { Data = languages.Select(x => x.ToModel()), Total = languages.Count() }; + return View(gridModel); } @@ -126,7 +151,7 @@ public ActionResult List(GridCommand command) { var model = new GridModel(); - if (_permissionService.Authorize(StandardPermissionProvider.ManageLanguages)) + if (_services.Permissions.Authorize(StandardPermissionProvider.ManageLanguages)) { var languages = _languageService.GetAllLanguages(true); @@ -148,26 +173,20 @@ public ActionResult List(GridCommand command) public ActionResult Create() { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageLanguages)) + if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageLanguages)) return AccessDeniedView(); var model = new LanguageModel(); - //flags - PrepareFlagsModel(model); - - //Stores - PrepareStoresMappingModel(model, null, false); + PrepareLanguageModel(model, null, false); - //default values - //model.Published = true; return View(model); } [HttpPost, ParameterBasedOnFormName("save-continue", "continueEditing")] public ActionResult Create(LanguageModel model, bool continueEditing) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageLanguages)) + if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageLanguages)) return AccessDeniedView(); if (ModelState.IsValid) @@ -183,18 +202,14 @@ public ActionResult Create(LanguageModel model, bool continueEditing) foreach (var plugin in plugins) { - _localizationService.ImportPluginResourcesFromXml(plugin, null, false, filterLanguages); + _services.Localization.ImportPluginResourcesFromXml(plugin, null, false, filterLanguages); } - NotifySuccess(_localizationService.GetResource("Admin.Configuration.Languages.Added")); + NotifySuccess(T("Admin.Configuration.Languages.Added")); return continueEditing ? RedirectToAction("Edit", new { id = language.Id }) : RedirectToAction("List"); } - //flags - PrepareFlagsModel(model); - - //Stores - PrepareStoresMappingModel(model, null, true); + PrepareLanguageModel(model, null, true); //If we got this far, something failed, redisplay form return View(model); @@ -202,7 +217,7 @@ public ActionResult Create(LanguageModel model, bool continueEditing) public ActionResult Edit(int id) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageLanguages)) + if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageLanguages)) return AccessDeniedView(); var language = _languageService.GetLanguageById(id); @@ -214,11 +229,7 @@ public ActionResult Edit(int id) var model = language.ToModel(); - //flags - PrepareFlagsModel(model); - - //Stores - PrepareStoresMappingModel(model, language, false); + PrepareLanguageModel(model, language, false); return View(model); } @@ -226,7 +237,7 @@ public ActionResult Edit(int id) [HttpPost, ParameterBasedOnFormName("save-continue", "continueEditing")] public ActionResult Edit(LanguageModel model, bool continueEditing) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageLanguages)) + if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageLanguages)) return AccessDeniedView(); var language = _languageService.GetLanguageById(model.Id); @@ -252,15 +263,11 @@ public ActionResult Edit(LanguageModel model, bool continueEditing) _storeMappingService.SaveStoreMappings(language, model.SelectedStoreIds); //notification - NotifySuccess(_localizationService.GetResource("Admin.Configuration.Languages.Updated")); + NotifySuccess(T("Admin.Configuration.Languages.Updated")); return continueEditing ? RedirectToAction("Edit", new { id = language.Id }) : RedirectToAction("List"); } - //flags - PrepareFlagsModel(model); - - //Stores - PrepareStoresMappingModel(model, language, true); + PrepareLanguageModel(model, language, true); //If we got this far, something failed, redisplay form return View(model); @@ -269,7 +276,7 @@ public ActionResult Edit(LanguageModel model, bool continueEditing) [HttpPost] public ActionResult Delete(int id) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageLanguages)) + if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageLanguages)) return AccessDeniedView(); var language = _languageService.GetLanguageById(id); @@ -288,7 +295,7 @@ public ActionResult Delete(int id) _languageService.DeleteLanguage(language); //notification - NotifySuccess(_localizationService.GetResource("Admin.Configuration.Languages.Deleted")); + NotifySuccess(T("Admin.Configuration.Languages.Deleted")); return RedirectToAction("List"); } @@ -298,7 +305,7 @@ public ActionResult Delete(int id) public ActionResult Resources(int languageId) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageLanguages)) + if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageLanguages)) return AccessDeniedView(); ViewBag.AllLanguages = _languageService.GetAllLanguages(true) @@ -312,7 +319,7 @@ public ActionResult Resources(int languageId) ViewBag.LanguageId = languageId; ViewBag.LanguageName = language.Name; - var resources = _localizationService + var resources = _services.Localization .GetResourceValues(languageId, true) .Where(x => x.Key != "!!___EOF___!!" && x.Value != null) .OrderBy(x => x.Key) @@ -339,11 +346,11 @@ public ActionResult Resources(int languageId, GridCommand command) { var model = new GridModel(); - if (_permissionService.Authorize(StandardPermissionProvider.ManageLanguages)) + if (_services.Permissions.Authorize(StandardPermissionProvider.ManageLanguages)) { var language = _languageService.GetLanguageById(languageId); - var resources = _localizationService + var resources = _services.Localization .GetResourceValues(languageId, true) .OrderBy(x => x.Key) .Where(x => x.Key != "!!___EOF___!!" && x.Value != null) @@ -377,7 +384,7 @@ public ActionResult Resources(int languageId, GridCommand command) [GridAction(EnableCustomBinding = true)] public ActionResult ResourceUpdate(LanguageResourceModel model, GridCommand command) { - if (_permissionService.Authorize(StandardPermissionProvider.ManageLanguages)) + if (_services.Permissions.Authorize(StandardPermissionProvider.ManageLanguages)) { if (model.Name != null) model.Name = model.Name.Trim(); @@ -390,11 +397,11 @@ public ActionResult ResourceUpdate(LanguageResourceModel model, GridCommand comm return Content(modelStateErrors.FirstOrDefault()); } - var resource = _localizationService.GetLocaleStringResourceById(model.Id); + var resource = _services.Localization.GetLocaleStringResourceById(model.Id); // if the resourceName changed, ensure it isn't being used by another resource if (!resource.ResourceName.Equals(model.Name, StringComparison.InvariantCultureIgnoreCase)) { - var res = _localizationService.GetLocaleStringResourceByName(model.Name, model.LanguageId, false); + var res = _services.Localization.GetLocaleStringResourceByName(model.Name, model.LanguageId, false); if (res != null && res.Id != resource.Id) { return Content(T("Admin.Configuration.Languages.Resources.NameAlreadyExists", res.ResourceName)); @@ -405,7 +412,7 @@ public ActionResult ResourceUpdate(LanguageResourceModel model, GridCommand comm resource.ResourceValue = model.Value; resource.IsTouched = true; - _localizationService.UpdateLocaleStringResource(resource); + _services.Localization.UpdateLocaleStringResource(resource); } return Resources(model.LanguageId, command); @@ -414,7 +421,7 @@ public ActionResult ResourceUpdate(LanguageResourceModel model, GridCommand comm [GridAction(EnableCustomBinding = true)] public ActionResult ResourceAdd(int id, LanguageResourceModel model, GridCommand command) { - if (_permissionService.Authorize(StandardPermissionProvider.ManageLanguages)) + if (_services.Permissions.Authorize(StandardPermissionProvider.ManageLanguages)) { if (model.Name != null) model.Name = model.Name.Trim(); @@ -427,7 +434,7 @@ public ActionResult ResourceAdd(int id, LanguageResourceModel model, GridCommand return Content(modelStateErrors.FirstOrDefault()); } - var res = _localizationService.GetLocaleStringResourceByName(model.Name, model.LanguageId, false); + var res = _services.Localization.GetLocaleStringResourceByName(model.Name, model.LanguageId, false); if (res == null) { var resource = new LocaleStringResource { LanguageId = id }; @@ -435,7 +442,7 @@ public ActionResult ResourceAdd(int id, LanguageResourceModel model, GridCommand resource.ResourceValue = model.Value; resource.IsTouched = true; - _localizationService.InsertLocaleStringResource(resource); + _services.Localization.InsertLocaleStringResource(resource); } else { @@ -449,11 +456,11 @@ public ActionResult ResourceAdd(int id, LanguageResourceModel model, GridCommand [GridAction(EnableCustomBinding = true)] public ActionResult ResourceDelete(int id, int languageId, GridCommand command) { - if (_permissionService.Authorize(StandardPermissionProvider.ManageLanguages)) + if (_services.Permissions.Authorize(StandardPermissionProvider.ManageLanguages)) { - var resource = _localizationService.GetLocaleStringResourceById(id); + var resource = _services.Localization.GetLocaleStringResourceById(id); - _localizationService.DeleteLocaleStringResource(resource); + _services.Localization.DeleteLocaleStringResource(resource); } return Resources(languageId, command); @@ -465,7 +472,7 @@ public ActionResult ResourceDelete(int id, int languageId, GridCommand command) public ActionResult ExportXml(int id) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageLanguages)) + if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageLanguages)) return AccessDeniedView(); var language = _languageService.GetLanguageById(id); @@ -474,7 +481,7 @@ public ActionResult ExportXml(int id) try { - var xml = _localizationService.ExportResourcesToXml(language); + var xml = _services.Localization.ExportResourcesToXml(language); return new XmlDownloadResult(xml, "language-pack-{0}.xml".FormatInvariant(language.UniqueSeoCode)); } catch (Exception exc) @@ -487,7 +494,7 @@ public ActionResult ExportXml(int id) [HttpPost] public ActionResult ImportXml(int id, FormCollection form, ImportModeFlags mode, bool updateTouched) { - if (!_permissionService.Authorize(StandardPermissionProvider.ManageLanguages)) + if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageLanguages)) return AccessDeniedView(); var language = _languageService.GetLanguageById(id); @@ -502,15 +509,15 @@ public ActionResult ImportXml(int id, FormCollection form, ImportModeFlags mode, var file = Request.Files["importxmlfile"]; if (file != null && file.ContentLength > 0) { - _localizationService.ImportResourcesFromXml(language, file.InputStream.AsString(), mode: mode, updateTouchedResources: updateTouched); + _services.Localization.ImportResourcesFromXml(language, file.InputStream.AsString(), mode: mode, updateTouchedResources: updateTouched); } else { - NotifyError(_localizationService.GetResource("Admin.Common.UploadFile")); + NotifyError(T("Admin.Common.UploadFile")); return RedirectToAction("Edit", new { id = language.Id }); } - NotifySuccess(_localizationService.GetResource("Admin.Configuration.Languages.Imported")); + NotifySuccess(T("Admin.Configuration.Languages.Imported")); return RedirectToAction("Edit", new { id = language.Id }); } catch (Exception exc) diff --git a/src/Presentation/SmartStore.Web/Administration/Infrastructure/AutoMapperStartupTask.cs b/src/Presentation/SmartStore.Web/Administration/Infrastructure/AutoMapperStartupTask.cs index 3cbb5afe21..cf6652c228 100644 --- a/src/Presentation/SmartStore.Web/Administration/Infrastructure/AutoMapperStartupTask.cs +++ b/src/Presentation/SmartStore.Web/Administration/Infrastructure/AutoMapperStartupTask.cs @@ -129,7 +129,9 @@ public void Execute() .ForMember(dest => dest.Country, mo => mo.Ignore()); //language Mapper.CreateMap() - .ForMember(dest => dest.FlagFileNames, mo => mo.Ignore()) + .ForMember(dest => dest.AvailableFlags, mo => mo.Ignore()) + .ForMember(dest => dest.AvailableCultures, mo => mo.Ignore()) + .ForMember(dest => dest.AvailableTwoLetterLanguageCodes, mo => mo.Ignore()) .ForMember(dest => dest.AvailableStores, mo => mo.Ignore()) .ForMember(dest => dest.SelectedStoreIds, mo => mo.Ignore()); Mapper.CreateMap() diff --git a/src/Presentation/SmartStore.Web/Administration/Models/Localization/LanguageModel.cs b/src/Presentation/SmartStore.Web/Administration/Models/Localization/LanguageModel.cs index b720c69d5f..28d3dfaf30 100644 --- a/src/Presentation/SmartStore.Web/Administration/Models/Localization/LanguageModel.cs +++ b/src/Presentation/SmartStore.Web/Administration/Models/Localization/LanguageModel.cs @@ -8,7 +8,7 @@ namespace SmartStore.Admin.Models.Localization { - [Validator(typeof(LanguageValidator))] + [Validator(typeof(LanguageValidator))] public class LanguageModel : EntityModelBase { public LanguageModel() @@ -23,18 +23,21 @@ public LanguageModel() [SmartResourceDisplayName("Admin.Configuration.Languages.Fields.LanguageCulture")] [AllowHtml] public string LanguageCulture { get; set; } + public List AvailableCultures { get; set; } - [SmartResourceDisplayName("Admin.Configuration.Languages.Fields.UniqueSeoCode")] + [SmartResourceDisplayName("Admin.Configuration.Languages.Fields.UniqueSeoCode")] [AllowHtml] public string UniqueSeoCode { get; set; } + public List AvailableTwoLetterLanguageCodes { get; set; } - //flags - [SmartResourceDisplayName("Admin.Configuration.Languages.Fields.FlagImageFileName")] + //flags + [SmartResourceDisplayName("Admin.Configuration.Languages.Fields.FlagImageFileName")] [AllowHtml] public string FlagImageFileName { get; set; } public IList FlagFileNames { get; set; } + public List AvailableFlags { get; set; } - [SmartResourceDisplayName("Admin.Configuration.Languages.Fields.Rtl")] + [SmartResourceDisplayName("Admin.Configuration.Languages.Fields.Rtl")] public bool Rtl { get; set; } [SmartResourceDisplayName("Admin.Configuration.Languages.Fields.Published")] diff --git a/src/Presentation/SmartStore.Web/Administration/Validators/Localization/LanguageValidator.cs b/src/Presentation/SmartStore.Web/Administration/Validators/Localization/LanguageValidator.cs index ea6ba1314e..891c093efc 100644 --- a/src/Presentation/SmartStore.Web/Administration/Validators/Localization/LanguageValidator.cs +++ b/src/Presentation/SmartStore.Web/Administration/Validators/Localization/LanguageValidator.cs @@ -9,29 +9,32 @@ public partial class LanguageValidator : AbstractValidator { public LanguageValidator(ILocalizationService localizationService) { - RuleFor(x => x.Name).NotEmpty().WithMessage(localizationService.GetResource("Admin.Configuration.Languages.Fields.Name.Required")); + RuleFor(x => x.Name) + .NotEmpty() + .WithMessage(localizationService.GetResource("Admin.Configuration.Languages.Fields.Name.Required")); + RuleFor(x => x.LanguageCulture) .Must(x => - { - try - { - var culture = new CultureInfo(x); - return culture != null; - } - catch - { - return false; - } - }) + { + try + { + var culture = new CultureInfo(x); + return culture != null; + } + catch + { + return false; + } + }) .WithMessage(localizationService.GetResource("Admin.Configuration.Languages.Fields.LanguageCulture.Validation")); RuleFor(x => x.UniqueSeoCode) .NotNull() .WithMessage(localizationService.GetResource("Admin.Configuration.Languages.Fields.UniqueSeoCode.Required")); + RuleFor(x => x.UniqueSeoCode) .Length(2) .WithMessage(localizationService.GetResource("Admin.Configuration.Languages.Fields.UniqueSeoCode.Length")); - } } } \ No newline at end of file diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Language/List.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Language/List.cshtml index 362dd5f5a6..91c1fe8140 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Language/List.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Language/List.cshtml @@ -1,7 +1,6 @@ @model Telerik.Web.Mvc.GridModel @using Telerik.Web.Mvc.UI @{ - //page title ViewBag.Title = T("Admin.Configuration.Languages").Text; }
@@ -24,7 +23,7 @@ columns.Bound(x => x.Name) .Template(x => Html.ActionLink(x.Name, "Edit", new { id = x.Id })); columns.Bound(x => x.LanguageCulture) - .Width(150) + .Width(200) .Centered(); columns.Template( @
@@ -34,10 +33,10 @@ .Centered() .Title(T("Admin.Configuration.Languages.Resources.View").Text); columns.Bound(x => x.DisplayOrder) - .Width(100) + .Width(200) .Centered(); columns.Bound(x => x.Published) - .Width(100) + .Width(200) .Template(item => @Html.SymbolForBool(item.Published)) .ClientTemplate(@Html.SymbolForBool("Published")) .Centered(); diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Language/_CreateOrUpdate.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Language/_CreateOrUpdate.cshtml index 621e963481..7f393dd8c5 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Language/_CreateOrUpdate.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Language/_CreateOrUpdate.cshtml @@ -1,9 +1,7 @@ -@model LanguageModel +@using SmartStore.Web.Framework.UI; +@model LanguageModel -@using Telerik.Web.Mvc.UI; -@using SmartStore.Web.Framework.UI; - -@Html.ValidationSummary(true) +@Html.ValidationSummary(false) @Html.HiddenFor(model => model.Id) @Html.SmartStore().TabStrip().Name("language-edit").Style(TabsStyle.Tabs).Position(TabsPosition.Top).Items(x => { @@ -16,20 +14,7 @@ @helper TabInfo() { - var cultures = System.Globalization.CultureInfo.GetCultures(System.Globalization.CultureTypes.SpecificCultures).ToList(); - - - +
@@ -54,7 +38,7 @@ @Html.SmartLabelFor(model => model.UniqueSeoCode) @@ -63,20 +47,15 @@ @Html.SmartLabelFor(model => model.FlagImageFileName) @@ -118,9 +97,40 @@ toggleStoreMapping(); - $("#pnlAllFlags a.flag").click(function () { - $("#FlagImageFileName").val($(this).data("filename")); + // init flags select + $('#LanguageEditTable').find('select[name=FlagImageFileName]').select2({ + allowClear: true, + minimumResultsForSearch: 16, + formatResult: flagSelectItemFormatting, + formatSelection: flagSelectItemFormatting }); + + function flagSelectItemFormatting(item) { + var flagUrl = '@Url.Content("~/Content/Images/flags/")'; + + try { + if (item.text.length > 0) { + var option = $(item.element), + html = '
'; + + // item.element is undefined for selection formatting + if (option.length === 0) { + option = $('select[name="FlagImageFileName"]').find('option[value="' + item.id + '"]'); + } + + if (option.length !== 0) { + html += '
'; + } + + html += '' + item.text + '
'; + + return html; + } + } + catch (e) { } + + return item.text; + } }); @@ -132,8 +142,8 @@ $('#pnl-available-stores').hide(); } } - +
@Html.SmartLabelFor(model => model.Name) @@ -44,8 +29,7 @@ @Html.SmartLabelFor(model => model.LanguageCulture) - @Html.DropDownListFor(x => x.LanguageCulture, cultures.Select(x => - new SelectListItem { Value = x.IetfLanguageTag, Text = string.Format("{0} [{1}]", x.DisplayName, x.IetfLanguageTag) })) + @Html.DropDownListFor(x => x.LanguageCulture, Model.AvailableCultures) @Html.ValidationMessageFor(model => model.LanguageCulture)
- @Html.EditorFor(model => model.UniqueSeoCode) + @Html.DropDownListFor(x => x.UniqueSeoCode, Model.AvailableTwoLetterLanguageCodes) @Html.ValidationMessageFor(model => model.UniqueSeoCode)
- @Html.EditorFor(model => model.FlagImageFileName) + @Html.ValidationMessageFor(model => model.FlagImageFileName) -
- @T("Admin.Common.Show") -
From c1a189e89bb48c296704eaecd1b2380f2a472385 Mon Sep 17 00:00:00 2001 From: Michael Herzog Date: Mon, 11 Jan 2016 14:54:42 +0100 Subject: [PATCH 145/626] Suppresses opening of a non existing link in a new window according to forum post 47526 --- .../SmartStore.Web/Views/Checkout/Confirm.cshtml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Presentation/SmartStore.Web/Views/Checkout/Confirm.cshtml b/src/Presentation/SmartStore.Web/Views/Checkout/Confirm.cshtml index fed6c42b8a..30d4231846 100644 --- a/src/Presentation/SmartStore.Web/Views/Checkout/Confirm.cshtml +++ b/src/Presentation/SmartStore.Web/Views/Checkout/Confirm.cshtml @@ -8,8 +8,8 @@ //title Html.AddTitleParts(T("PageTitle.Checkout").Text); - string termsLink = ""; - string disclaimerLink = ""; + string termsLink = ""; + string disclaimerLink = ""; string terms = string.Format(T("Checkout.TermsOfService.IAccept"), termsLink, "", disclaimerLink); } @section orderProgress{ @@ -38,7 +38,7 @@ $("#terms-of-service-modal .modal-body").html('