diff --git a/headers/libs/print/libprint/JobData.h b/headers/libs/print/libprint/JobData.h index ee0708802f..b418f37a2d 100644 --- a/headers/libs/print/libprint/JobData.h +++ b/headers/libs/print/libprint/JobData.h @@ -22,6 +22,38 @@ class PrinterCap; using namespace std; +class DriverSpecificSettings +{ +public: + DriverSpecificSettings(); + DriverSpecificSettings(const DriverSpecificSettings& settings); + + DriverSpecificSettings &operator=(const DriverSpecificSettings &settings); + + void MakeEmpty(); + + bool HasString(const char* key) const; + const char* GetString(const char* key) const; + void SetString(const char* key, const char* value); + + bool HasBoolean(const char* ekey) const; + bool GetBoolean(const char* key) const; + void SetBoolean(const char* key, bool value); + + bool HasInt(const char* ekey) const; + int32 GetInt(const char* key) const; + void SetInt(const char* key, int32 value); + + bool HasDouble(const char* ekey) const; + double GetDouble(const char* key) const; + void SetDouble(const char* key, double value); + + BMessage& Message(); + +private: + BMessage fSettings; +}; + class JobData { public: @@ -219,7 +251,7 @@ public: kColorCompressionDisabled }; - enum Settings { + enum SettingType { kPageSettings, kJobSettings }; @@ -256,22 +288,22 @@ private: PrintStyle fPrintStyle; BindingLocation fBindingLocation; PageOrder fPageOrder; - Settings fSettings; + SettingType fSettingType; BMessage *fMsg; Color fColor; Halftone::DitherType fDitherType; PageSelection fPageSelection; MarginUnit fMarginUnit; - map fDriverSpecificSettings; + DriverSpecificSettings fDriverSpecificSettings; public: - JobData(BMessage *msg, const PrinterCap *cap, Settings settings); + JobData(BMessage *msg, const PrinterCap *cap, SettingType type); ~JobData(); JobData(const JobData &job_data); JobData &operator = (const JobData &job_data); - void load(BMessage *msg, const PrinterCap *cap, Settings settings); + void load(BMessage *msg, const PrinterCap *cap, SettingType type); void save(BMessage *msg = NULL); bool getShowPreview() const { return fShowPreview; } @@ -364,13 +396,9 @@ public: MarginUnit getMarginUnit() const { return fMarginUnit; } void setMarginUnit(MarginUnit marginUnit) { fMarginUnit = marginUnit; } - bool HasDriverSpecificSetting(const string& category) const; - const string& DriverSpecificSetting(const string& category) const; - void SetDriverSpecificSetting(const string& category, const string& value); + DriverSpecificSettings& Settings(); + const DriverSpecificSettings& Settings() const; -private: - void SerializePrinterSpecificSettings(BString& serializedSettings); - void DeserializePrinterSpecificSettings(BString& serializedSettings); }; #endif /* __JOBDATA_H */ diff --git a/headers/libs/print/libprint/JobSetupDlg.h b/headers/libs/print/libprint/JobSetupDlg.h index 561245100b..751aed7c34 100644 --- a/headers/libs/print/libprint/JobSetupDlg.h +++ b/headers/libs/print/libprint/JobSetupDlg.h @@ -20,6 +20,7 @@ class BCheckBox; class BGridLayout; class BPopUpMenu; class BRadioButton; +class BSlider; class BTextControl; class BTextView; class HalftoneView; @@ -28,6 +29,79 @@ class PagesView; class PrinterCap; class PrinterData; +extern BString& operator<<(BString& text, double value); + +template +class Range +{ +public: + Range(); + Range(const char* label, const char* key, const R* range, BSlider* slider); + const char* Key() const; + T Value(); + void UpdateLabel(); + +private: + const char* fLabel; + const char* fKey; + const R* fRange; + BSlider* fSlider; +}; + + +template +Range::Range() + : + fKey(NULL), + fRange(NULL), + fSlider(NULL) +{ +} + + +template +Range::Range(const char* label, const char* key, const R* range, + BSlider* slider) + : + fLabel(label), + fKey(key), + fRange(range), + fSlider(slider) +{ + +} + + +template +const char* +Range::Key() const +{ + return fKey; +} + + +template +T +Range::Value() +{ + return static_cast(fRange->Lower() + + (fRange->Upper() - fRange->Lower()) * fSlider->Position()); +} + + +template +void +Range::UpdateLabel() +{ + BString label = fLabel; + label << " (" << Value() << ")"; + fSlider->SetLabel(label.String()); +} + + +typedef Range IntRange; +typedef Range DoubleRange; + class JobSetupView : public BView { public: JobSetupView(JobData* jobData, PrinterData* printerData, @@ -41,6 +115,14 @@ private: bool IsHalftoneConfigurationNeeded(); void CreateHalftoneConfigurationUI(); void AddDriverSpecificSettings(BGridLayout* gridLayout, int row); + void AddPopUpMenu(const DriverSpecificCap* capability, + BGridLayout* gridLayout, int& row); + void AddCheckBox(const DriverSpecificCap* capability, + BGridLayout* gridLayout, int& row); + void AddIntSlider(const DriverSpecificCap* capability, + BGridLayout* gridLayout, int& row); + void AddDoubleSlider(const DriverSpecificCap* capability, + BGridLayout* gridLayout, int& row); string GetDriverSpecificValue(PrinterCap::CapID category, const char* key); template @@ -58,6 +140,8 @@ private: JobData::PageSelection pageSelection); void AllowOnlyDigits(BTextView* textView, int maxDigits); void UpdateHalftonePreview(); + void UpdateIntSlider(BMessage* message); + void UpdateDoubleSlider(BMessage* message); JobData::Color Color(); Halftone::DitherType DitherType(); @@ -65,6 +149,7 @@ private: float InkDensity(); JobData::PaperSource PaperSource(); + BTextControl* fCopies; BTextControl* fFromPage; BTextControl* fToPage; @@ -88,7 +173,10 @@ private: BRadioButton* fAllPages; BRadioButton* fOddNumberedPages; BRadioButton* fEvenNumberedPages; - std::map fDriverSpecificLists; + std::map fDriverSpecificPopUpMenus; + std::map fDriverSpecificCheckBoxes; + std::map fDriverSpecificIntSliders; + std::map fDriverSpecificDoubleSliders; BCheckBox* fPreview; }; diff --git a/headers/libs/print/libprint/PrinterCap.h b/headers/libs/print/libprint/PrinterCap.h index 004e523d99..b1cba56132 100644 --- a/headers/libs/print/libprint/PrinterCap.h +++ b/headers/libs/print/libprint/PrinterCap.h @@ -17,18 +17,26 @@ enum { }; struct BaseCap { - BaseCap(const string &label, bool isDefault); + BaseCap(const string &label); virtual ~BaseCap(); + const char* Label() const; + + string fLabel; +}; + +struct EnumCap : public BaseCap { + EnumCap(const string& label, bool isDefault); + virtual int32 ID() const = 0; const char* Key() const; - string fLabel; bool fIsDefault; string fKey; }; -struct PaperCap : public BaseCap { + +struct PaperCap : public EnumCap { PaperCap(const string &label, bool isDefault, JobData::Paper paper, const BRect &paperRect, const BRect &physicalRect); @@ -40,7 +48,7 @@ struct PaperCap : public BaseCap { BRect fPhysicalRect; }; -struct PaperSourceCap : public BaseCap { +struct PaperSourceCap : public EnumCap { PaperSourceCap(const string &label, bool isDefault, JobData::PaperSource paperSource); @@ -49,7 +57,7 @@ struct PaperSourceCap : public BaseCap { JobData::PaperSource fPaperSource; }; -struct ResolutionCap : public BaseCap { +struct ResolutionCap : public EnumCap { ResolutionCap(const string &label, bool isDefault, int32 id, int xResolution, int yResolution); @@ -60,7 +68,7 @@ struct ResolutionCap : public BaseCap { int fYResolution; }; -struct OrientationCap : public BaseCap { +struct OrientationCap : public EnumCap { OrientationCap(const string &label, bool isDefault, JobData::Orientation orientation); @@ -69,7 +77,7 @@ struct OrientationCap : public BaseCap { JobData::Orientation fOrientation; }; -struct PrintStyleCap : public BaseCap { +struct PrintStyleCap : public EnumCap { PrintStyleCap(const string &label, bool isDefault, JobData::PrintStyle printStyle); @@ -78,7 +86,7 @@ struct PrintStyleCap : public BaseCap { JobData::PrintStyle fPrintStyle; }; -struct BindingLocationCap : public BaseCap { +struct BindingLocationCap : public EnumCap { BindingLocationCap(const string &label, bool isDefault, JobData::BindingLocation bindingLocation); @@ -88,7 +96,7 @@ struct BindingLocationCap : public BaseCap { JobData::BindingLocation fBindingLocation; }; -struct ColorCap : public BaseCap { +struct ColorCap : public EnumCap { ColorCap(const string &label, bool isDefault, JobData::Color color); @@ -97,7 +105,7 @@ struct ColorCap : public BaseCap { JobData::Color fColor; }; -struct ProtocolClassCap : public BaseCap { +struct ProtocolClassCap : public EnumCap { ProtocolClassCap(const string &label, bool isDefault, int32 protocolClass, const string &description); @@ -109,11 +117,13 @@ struct ProtocolClassCap : public BaseCap { }; -struct DriverSpecificCap : public BaseCap { +struct DriverSpecificCap : public EnumCap { enum Type { kList, - kCheckBox, - kRange + kBoolean, + kIntRange, + kIntDimension, + kDoubleRange }; DriverSpecificCap(const string& label, @@ -125,14 +135,52 @@ struct DriverSpecificCap : public BaseCap { Type fType; }; -struct ListItemCap : public BaseCap { +struct ListItemCap : public EnumCap { ListItemCap(const string& label, bool isDefault, int32 id); int32 ID() const; + +private: int32 fID; }; +struct BooleanCap : public BaseCap { + BooleanCap(const string& label, bool defaultValue); + + bool DefaultValue() const; + +private: + bool fDefaultValue; +}; + +struct IntRangeCap : public BaseCap { + IntRangeCap(const string& label, int lower, + int upper, int defaultValue); + + int32 Lower() const; + int32 Upper() const; + int32 DefaultValue() const; + +private: + int32 fLower; + int32 fUpper; + int32 fDefaultValue; +}; + +struct DoubleRangeCap : public BaseCap { + DoubleRangeCap(const string& label, double lower, + double upper, double defaultValue); + + double Lower() const; + double Upper() const; + double DefaultValue() const; + + double fLower; + double fUpper; + double fDefaultValue; +}; + class PrinterData; class PrinterCap { @@ -170,7 +218,10 @@ public: bool operator()(const BaseCap* baseCap) { - return baseCap->ID() == fID; + const EnumCap* enumCap = dynamic_cast(baseCap); + if (enumCap == NULL) + return false; + return enumCap->ID() == fID; } int fID; @@ -201,7 +252,10 @@ public: bool operator()(const BaseCap* baseCap) { - return baseCap->fKey == fKey; + const EnumCap* enumCap = dynamic_cast(baseCap); + if (enumCap == NULL) + return false; + return enumCap->fKey == fKey; } const char* fKey; @@ -211,12 +265,16 @@ public: virtual int countCap(CapID category) const = 0; virtual bool isSupport(CapID category) const = 0; virtual const BaseCap** enumCap(CapID category) const = 0; - const BaseCap* getDefaultCap(CapID category) const; - const BaseCap* findCap(CapID category, int id) const; + const EnumCap* getDefaultCap(CapID category) const; + const EnumCap* findCap(CapID category, int id) const; const BaseCap* findCap(CapID category, const char* label) const; - const BaseCap* findCapWithKey(CapID category, const char* key) + const EnumCap* findCapWithKey(CapID category, const char* key) const; + const BooleanCap* findBooleanCap(CapID category) const; + const IntRangeCap* findIntRangeCap(CapID category) const; + const DoubleRangeCap* findDoubleRangeCap(CapID category) const; + int getProtocolClass() const; protected: diff --git a/src/add-ons/print/drivers/gutenprint/GPCapabilityExtractor.cpp b/src/add-ons/print/drivers/gutenprint/GPCapabilityExtractor.cpp index 7081ee2b24..e3d8258edb 100644 --- a/src/add-ons/print/drivers/gutenprint/GPCapabilityExtractor.cpp +++ b/src/add-ons/print/drivers/gutenprint/GPCapabilityExtractor.cpp @@ -51,9 +51,7 @@ GPCapabilityExtractor::BeginParameter(const char* name, const char* displayName, fState = kExtractPrintingModeParameter; } else { GP_PRINT("Parameter: %s - %s\n", name, displayName); - bool recordParameter = parameterClass == STP_PARAMETER_CLASS_FEATURE || - parameterClass == STP_PARAMETER_CLASS_OUTPUT; - if (!recordParameter) + if (!IsSupported(parameterClass)) return false; fState = kExtractParameter; @@ -117,7 +115,7 @@ GPCapabilityExtractor::StringParameter(const char* name, const char* key, const char* displayName) { bool isDefault = fDefaultKey == key; - BaseCap* capability; + EnumCap* capability; switch (fState) { case kExtractResolutionParameter: @@ -154,7 +152,7 @@ GPCapabilityExtractor::ResolutionParameter(const char* name, const char* key, const char* displayName, int x, int y) { bool isDefault = fDefaultKey == key; - BaseCap* capability; + EnumCap* capability; int resolution; switch (fState) { @@ -188,7 +186,7 @@ GPCapabilityExtractor::PageSizeParameter(const char* name, const char* key, const char* displayName, BSize pageSize, BRect imageableArea) { bool isDefault = fDefaultKey == key; - BaseCap* capability; + EnumCap* capability; switch (fState) { case kExtractPageSizeParameter: @@ -214,6 +212,65 @@ GPCapabilityExtractor::EndParameter(const char* name) } +void +GPCapabilityExtractor::BooleanParameter(const char* name, + const char* displayName, bool defaultValue, + stp_parameter_class_t parameterClass) +{ + if (!IsSupported(parameterClass)) + return; + + BooleanCap* capability = new BooleanCap(displayName, defaultValue); + AddDriverSpecificCapability(name, displayName, DriverSpecificCap::kBoolean, + capability); +} + + +void +GPCapabilityExtractor::DoubleParameter(const char* name, + const char* displayName, double lower, double upper, double defaultValue, + stp_parameter_class_t parameterClass) +{ + if (!IsSupported(parameterClass)) + return; + + DoubleRangeCap* capability = new DoubleRangeCap(displayName, lower, upper, + defaultValue); + AddDriverSpecificCapability(name, displayName, + DriverSpecificCap::kDoubleRange, capability); +} + + +void +GPCapabilityExtractor::IntParameter(const char* name, const char* displayName, + int lower, int upper, int defaultValue, + stp_parameter_class_t parameterClass) +{ + if (!IsSupported(parameterClass)) + return; + + IntRangeCap* capability = new IntRangeCap(displayName, lower, upper, + defaultValue); + AddDriverSpecificCapability(name, displayName, DriverSpecificCap::kIntRange, + capability); +} + + +void +GPCapabilityExtractor::DimensionParameter(const char* name, + const char* displayName, int lower, int upper, int defaultValue, + stp_parameter_class_t parameterClass) +{ + if (!IsSupported(parameterClass)) + return; + + IntRangeCap* capability = new IntRangeCap(displayName, lower, upper, + defaultValue); + AddDriverSpecificCapability(name, displayName, + DriverSpecificCap::kIntDimension, capability); +} + + void GPCapabilityExtractor::EndVisit() { @@ -223,6 +280,14 @@ GPCapabilityExtractor::EndVisit() } +bool +GPCapabilityExtractor::IsSupported(stp_parameter_class_t parameterClass) +{ + return parameterClass == STP_PARAMETER_CLASS_FEATURE + || parameterClass == STP_PARAMETER_CLASS_OUTPUT; +} + + void GPCapabilityExtractor::AddDefaultInputSlot() { @@ -252,9 +317,28 @@ GPCapabilityExtractor::SetDriverSpecificCategories() void GPCapabilityExtractor::AddCapability(GPArray& array, - BaseCap* capability, const char* key) + EnumCap* capability, const char* key) { capability->fKey = key; array.Array()[fIndex] = capability; fIndex ++; } + + +void +GPCapabilityExtractor::AddDriverSpecificCapability(const char* name, + const char* displayName, DriverSpecificCap::Type type, BaseCap* capability) +{ + DriverSpecificCap* parent = new DriverSpecificCap(displayName, + fNextDriverSpecificCategoryID, type); + parent->fKey = name; + + fDriverSpecificCategories.push_back(parent); + + GPArray& array = fCapabilities->fDriverSpecificCapabilities + [fNextDriverSpecificCategoryID]; + array.SetSize(1); + array.Array()[0] = capability; + + fNextDriverSpecificCategoryID++; +} diff --git a/src/add-ons/print/drivers/gutenprint/GPCapabilityExtractor.h b/src/add-ons/print/drivers/gutenprint/GPCapabilityExtractor.h index 6d1e254a55..45a31c7660 100644 --- a/src/add-ons/print/drivers/gutenprint/GPCapabilityExtractor.h +++ b/src/add-ons/print/drivers/gutenprint/GPCapabilityExtractor.h @@ -42,13 +42,28 @@ public: void PageSizeParameter(const char* name, const char* key, const char* displayName, BSize pageSize, BRect imageableArea); void EndParameter(const char* name); + void BooleanParameter(const char* name, const char* displayName, + bool defaultValue, + stp_parameter_class_t parameterClass); + void DoubleParameter(const char* name, const char* displayName, + double lower, double upper, double defaultValue, + stp_parameter_class_t parameterClass); + void IntParameter(const char* name, const char* displayName, int lower, + int upper, int defaultValue, + stp_parameter_class_t parameterClass); + void DimensionParameter(const char* name, const char* displayName, + int lower, int upper, int defaultValue, + stp_parameter_class_t parameterClass); void EndVisit(); protected: + bool IsSupported(stp_parameter_class_t parameterClass); void AddDefaultInputSlot(); void SetDriverSpecificCategories(); - void AddCapability(GPArray& array, BaseCap* capability, + void AddCapability(GPArray& array, EnumCap* capability, const char* key); + void AddDriverSpecificCapability(const char* name, const char* + displayName, DriverSpecificCap::Type type, BaseCap* capability); private: GPCapabilityExtractorState fState; diff --git a/src/add-ons/print/drivers/gutenprint/GPDriver.cpp b/src/add-ons/print/drivers/gutenprint/GPDriver.cpp index b0204fee6c..7018c3d7b2 100644 --- a/src/add-ons/print/drivers/gutenprint/GPDriver.cpp +++ b/src/add-ons/print/drivers/gutenprint/GPDriver.cpp @@ -86,7 +86,7 @@ void GPDriver::SetParameter(BString& parameter, PrinterCap::CapID category, int value) { - const BaseCap* capability; + const EnumCap* capability; capability = getPrinterCap()->findCap(category, value); if (capability != NULL && capability->fKey != "") parameter = capability->Key(); @@ -100,19 +100,43 @@ GPDriver::SetDriverSpecificSettings() int count = getPrinterCap()->countCap(category); const BaseCap** capabilities = getPrinterCap()->enumCap(category); for (int i = 0; i < count; i++) { - const BaseCap* capability = capabilities[i]; + const DriverSpecificCap* capability = + dynamic_cast(capabilities[i]); + if (capability == NULL) { + fprintf(stderr, "Internal error: DriverSpecificCap name='%s' " + "has wrong type!\n", capabilities[i]->Label()); + continue; + } + PrinterCap::CapID id = static_cast(capability->ID()); - AddDriverSpecificSetting(id, capability->fKey.c_str()); + const char* key = capability->fKey.c_str(); + switch (capability->fType) { + case DriverSpecificCap::kList: + AddDriverSpecificSetting(id, key); + break; + case DriverSpecificCap::kBoolean: + AddDriverSpecificBooleanSetting(id, key); + break; + case DriverSpecificCap::kIntRange: + AddDriverSpecificIntSetting(id, key); + break; + case DriverSpecificCap::kIntDimension: + AddDriverSpecificDimensionSetting(id, key); + break; + case DriverSpecificCap::kDoubleRange: + AddDriverSpecificDoubleSetting(id, key); + break; + } } } void GPDriver::AddDriverSpecificSetting(PrinterCap::CapID category, const char* key) { - const BaseCap* capability = NULL; - if (getJobData()->HasDriverSpecificSetting(key)) + const EnumCap* capability = NULL; + if (getJobData()->Settings().HasString(key)) { - const string& value = getJobData()->DriverSpecificSetting(key); + const string& value = getJobData()->Settings().GetString(key); capability = getPrinterCap()->findCapWithKey(category, value.c_str()); } @@ -127,7 +151,43 @@ GPDriver::AddDriverSpecificSetting(PrinterCap::CapID category, const char* key) return; } - fConfiguration.fDriverSpecificSettings[key] = capability->fKey; + fConfiguration.fStringSettings[key] = capability->fKey; +} + + +void +GPDriver::AddDriverSpecificBooleanSetting(PrinterCap::CapID category, + const char* key) { + if (getJobData()->Settings().HasBoolean(key)) + fConfiguration.fBooleanSettings[key] = + getJobData()->Settings().GetBoolean(key); +} + + +void +GPDriver::AddDriverSpecificIntSetting(PrinterCap::CapID category, + const char* key) { + if (getJobData()->Settings().HasInt(key)) + fConfiguration.fIntSettings[key] = + getJobData()->Settings().GetInt(key); +} + + +void +GPDriver::AddDriverSpecificDimensionSetting(PrinterCap::CapID category, + const char* key) { + if (getJobData()->Settings().HasInt(key)) + fConfiguration.fDimensionSettings[key] = + getJobData()->Settings().GetInt(key); +} + + +void +GPDriver::AddDriverSpecificDoubleSetting(PrinterCap::CapID category, + const char* key) { + if (getJobData()->Settings().HasDouble(key)) + fConfiguration.fDoubleSettings[key] = + getJobData()->Settings().GetDouble(key); } diff --git a/src/add-ons/print/drivers/gutenprint/GPDriver.h b/src/add-ons/print/drivers/gutenprint/GPDriver.h index 336d22f049..e101e13e8f 100644 --- a/src/add-ons/print/drivers/gutenprint/GPDriver.h +++ b/src/add-ons/print/drivers/gutenprint/GPDriver.h @@ -30,6 +30,14 @@ protected: void SetDriverSpecificSettings(); void AddDriverSpecificSetting(PrinterCap::CapID category, const char* key); + void AddDriverSpecificBooleanSetting(PrinterCap::CapID category, + const char* key); + void AddDriverSpecificIntSetting(PrinterCap::CapID category, + const char* key); + void AddDriverSpecificDimensionSetting(PrinterCap::CapID category, + const char* key); + void AddDriverSpecificDoubleSetting(PrinterCap::CapID category, + const char* key); bool startPage(int page); bool nextBand(BBitmap* bitmap, BPoint* offset); bool endPage(int page); diff --git a/src/add-ons/print/drivers/gutenprint/GPJob.cpp b/src/add-ons/print/drivers/gutenprint/GPJob.cpp index 48cb53904a..d18bb16117 100644 --- a/src/add-ons/print/drivers/gutenprint/GPJob.cpp +++ b/src/add-ons/print/drivers/gutenprint/GPJob.cpp @@ -97,11 +97,49 @@ GPJob::Begin() stp_set_string_parameter(fVariables, "PrintingMode", fConfiguration->fPrintingMode); - map::iterator it = fConfiguration->fDriverSpecificSettings. - begin(); - for (; it != fConfiguration->fDriverSpecificSettings.end(); it ++) { - stp_set_string_parameter(fVariables, it->first.c_str(), - it->second.c_str()); + { + map::iterator it = fConfiguration->fStringSettings. + begin(); + for (; it != fConfiguration->fStringSettings.end(); it ++) { + stp_set_string_parameter(fVariables, it->first.c_str(), + it->second.c_str()); + } + } + + { + map::iterator it = fConfiguration->fBooleanSettings. + begin(); + for (; it != fConfiguration->fBooleanSettings.end(); it ++) { + stp_set_boolean_parameter(fVariables, it->first.c_str(), + it->second); + } + } + + { + map::iterator it = fConfiguration->fIntSettings. + begin(); + for (; it != fConfiguration->fIntSettings.end(); it ++) { + stp_set_int_parameter(fVariables, it->first.c_str(), + it->second); + } + } + + { + map::iterator it = fConfiguration->fDimensionSettings. + begin(); + for (; it != fConfiguration->fDimensionSettings.end(); it ++) { + stp_set_dimension_parameter(fVariables, it->first.c_str(), + it->second); + } + } + + { + map::iterator it = fConfiguration->fDoubleSettings. + begin(); + for (; it != fConfiguration->fDoubleSettings.end(); it ++) { + stp_set_float_parameter(fVariables, it->first.c_str(), + it->second); + } } stp_set_string_parameter(fVariables, "InputImageType", diff --git a/src/add-ons/print/drivers/gutenprint/GPJobConfiguration.h b/src/add-ons/print/drivers/gutenprint/GPJobConfiguration.h index e40eaa6c8f..f122dade3e 100644 --- a/src/add-ons/print/drivers/gutenprint/GPJobConfiguration.h +++ b/src/add-ons/print/drivers/gutenprint/GPJobConfiguration.h @@ -29,7 +29,11 @@ public: int fXDPI; int fYDPI; - map fDriverSpecificSettings; + map fStringSettings; + map fBooleanSettings; + map fIntSettings; + map fDimensionSettings; + map fDoubleSettings; }; #endif diff --git a/src/add-ons/print/drivers/gutenprint/GPParameterVisitor.cpp b/src/add-ons/print/drivers/gutenprint/GPParameterVisitor.cpp index 3273dd8918..78ee7167a1 100644 --- a/src/add-ons/print/drivers/gutenprint/GPParameterVisitor.cpp +++ b/src/add-ons/print/drivers/gutenprint/GPParameterVisitor.cpp @@ -125,6 +125,7 @@ GPParameterVisitor::VisitParameter(stp_parameter_list_t list, { // TODO decide which parameters should be revealed to user // e.g. up to STP_PARAMETER_LEVEL_ADVANCED4; + // const stp_parameter_level_t kMaxLevel = STP_PARAMETER_LEVEL_ADVANCED4; const stp_parameter_level_t kMaxLevel = STP_PARAMETER_LEVEL_BASIC; stp_parameter_class_t parameterClass = parameter->p_class; if (parameter->read_only || @@ -148,15 +149,19 @@ GPParameterVisitor::VisitParameter(stp_parameter_list_t list, break; case STP_PARAMETER_TYPE_BOOLEAN: + VisitBooleanParameter(description, parameterClass); break; case STP_PARAMETER_TYPE_DOUBLE: + VisitDoubleParameter(description, parameterClass); break; case STP_PARAMETER_TYPE_INT: + VisitIntParameter(description, parameterClass); break; case STP_PARAMETER_TYPE_DIMENSION: + VisitDimensionParameter(description, parameterClass); break; default: @@ -213,3 +218,58 @@ GPParameterVisitor::VisitStringList(stp_parameter_t* parameter) } } } + + +void +GPParameterVisitor::VisitBooleanParameter(stp_parameter_t* description, + stp_parameter_class_t parameterClass) +{ + bool defaultValue = true; + if (description->is_mandatory) + defaultValue = description->deflt.boolean; + BooleanParameter(description->name, description->text, defaultValue, + parameterClass); +} + + +void +GPParameterVisitor::VisitDoubleParameter(stp_parameter_t* description, + stp_parameter_class_t parameterClass) +{ + const char* name = description->name; + const char* text = description->text; + double lower = description->bounds.dbl.lower; + double upper = description->bounds.dbl.upper; + double defaultValue = description->deflt.dbl; + if (lower <= defaultValue && defaultValue <= upper) + DoubleParameter(name, text, lower, upper, defaultValue, parameterClass); +} + + +void +GPParameterVisitor::VisitIntParameter(stp_parameter_t* description, + stp_parameter_class_t parameterClass) +{ + const char* name = description->name; + const char* text = description->text; + int lower = description->bounds.integer.lower; + int upper = description->bounds.integer.upper; + int defaultValue = description->deflt.integer; + if (lower <= defaultValue && defaultValue <= upper) + IntParameter(name, text, lower, upper, defaultValue, parameterClass); +} + + +void +GPParameterVisitor::VisitDimensionParameter(stp_parameter_t* description, + stp_parameter_class_t parameterClass) +{ + const char* name = description->name; + const char* text = description->text; + int lower = description->bounds.dimension.lower; + int upper = description->bounds.dimension.upper; + int defaultValue = description->deflt.dimension; + if (lower <= defaultValue && defaultValue <= upper) + DimensionParameter(name, text, lower, upper, defaultValue, + parameterClass); +} diff --git a/src/add-ons/print/drivers/gutenprint/GPParameterVisitor.h b/src/add-ons/print/drivers/gutenprint/GPParameterVisitor.h index a9ee90f1a5..5d3862e97b 100644 --- a/src/add-ons/print/drivers/gutenprint/GPParameterVisitor.h +++ b/src/add-ons/print/drivers/gutenprint/GPParameterVisitor.h @@ -39,6 +39,14 @@ public: void VisitParameter(stp_parameter_list_t list, const stp_parameter_t* parameter, stp_parameter_t* description); void VisitStringList(stp_parameter_t* parameter); + void VisitBooleanParameter(stp_parameter_t* description, + stp_parameter_class_t parameterClass); + void VisitDoubleParameter(stp_parameter_t* description, + stp_parameter_class_t parameterClass); + void VisitIntParameter(stp_parameter_t* description, + stp_parameter_class_t parameterClass); + void VisitDimensionParameter(stp_parameter_t* description, + stp_parameter_class_t parameterClass); virtual bool BeginParameter(const char* name, const char* displayName, stp_parameter_class_t parameterClass) = 0; @@ -54,6 +62,19 @@ public: const char* displayName, BSize pageSize, BRect imageableArea) = 0; virtual void EndParameter(const char* name) = 0; + virtual void BooleanParameter(const char* name, const char* displayName, + bool defaultValue, + stp_parameter_class_t parameterClass) = 0; + virtual void DoubleParameter(const char* name, const char* displayName, + double lower, double upper, double defaultValue, + stp_parameter_class_t parameterClass) = 0; + virtual void IntParameter(const char* name, const char* displayName, + int lower, int upper, int defaultValue, + stp_parameter_class_t parameterClass) = 0; + virtual void DimensionParameter(const char* name, + const char* displayName, int lower, + int upper, int defaultValue, + stp_parameter_class_t parameterClass) = 0; virtual void EndVisit() = 0; private: diff --git a/src/add-ons/print/drivers/gutenprint/SelectPrinterDialog.cpp b/src/add-ons/print/drivers/gutenprint/SelectPrinterDialog.cpp index c7e8e7bf41..f563da005b 100644 --- a/src/add-ons/print/drivers/gutenprint/SelectPrinterDialog.cpp +++ b/src/add-ons/print/drivers/gutenprint/SelectPrinterDialog.cpp @@ -52,7 +52,7 @@ public: SelectPrinterDialog::SelectPrinterDialog(GPData* data) : - DialogWindow(BRect(10, 10, 400, 400), + DialogWindow(BRect(100, 100, 500, 500), "Select Printer", B_TITLED_WINDOW_LOOK, B_MODAL_APP_WINDOW_FEEL, B_NOT_MINIMIZABLE | B_NOT_ZOOMABLE | B_ASYNCHRONOUS_CONTROLS), fData(data) diff --git a/src/libs/print/libprint/JobData.cpp b/src/libs/print/libprint/JobData.cpp index 36bdf83088..198ad40d29 100644 --- a/src/libs/print/libprint/JobData.cpp +++ b/src/libs/print/libprint/JobData.cpp @@ -5,6 +5,7 @@ #include "JobData.h" +#include #include #include @@ -45,12 +46,157 @@ static const char* kJDScaledPhysicalRect = "JJJJ_scaled_physical_rect"; static const char* kJDResolution = "JJJJ_resolution"; static const char* kJDDriverSpecificSettings = "JJJJ_driverSpecificSettings"; -static const char* kDriverSpecificSettingsSeparator = ";"; - -JobData::JobData(BMessage *msg, const PrinterCap *cap, Settings settings) +DriverSpecificSettings::DriverSpecificSettings() { - load(msg, cap, settings); +} + + +DriverSpecificSettings::DriverSpecificSettings( + const DriverSpecificSettings& settings) + : + fSettings(settings.fSettings) +{ +} + + +DriverSpecificSettings & +DriverSpecificSettings::operator=(const DriverSpecificSettings &settings) +{ + fSettings = settings.fSettings; + return *this; +} + + +void +DriverSpecificSettings::MakeEmpty() +{ + fSettings.MakeEmpty(); +} + + +bool +DriverSpecificSettings::HasString(const char* key) const +{ + const char* value; + return fSettings.FindString(key, &value) == B_OK; +} + + +const char* +DriverSpecificSettings::GetString(const char* key) const +{ + ASSERT(HasString(key)); + const char* value = NULL; + fSettings.FindString(key, &value); + return value; +} + + +void +DriverSpecificSettings::SetString(const char* key, const char* value) +{ + if (HasString(key)) + fSettings.ReplaceString(key, value); + else + fSettings.AddString(key, value); +} + + +bool +DriverSpecificSettings::HasBoolean(const char* key) const +{ + bool value; + return fSettings.FindBool(key, &value) == B_OK; +} + + +bool +DriverSpecificSettings::GetBoolean(const char* key) const +{ + ASSERT(HasBoolean(key)); + bool value; + fSettings.FindBool(key, &value); + return value; +} + + +void +DriverSpecificSettings::SetBoolean(const char* key, bool value) +{ + if (HasBoolean(key)) + fSettings.ReplaceBool(key, value); + else + fSettings.AddBool(key, value); +} + + +bool +DriverSpecificSettings::HasInt(const char* key) const +{ + int32 value; + return fSettings.FindInt32(key, &value) == B_OK; +} + + +int32 +DriverSpecificSettings::GetInt(const char* key) const +{ + ASSERT(HasInt(key)); + int32 value; + fSettings.FindInt32(key, &value); + return value; +} + + +void +DriverSpecificSettings::SetInt(const char* key, int32 value) +{ + if (HasInt(key)) + fSettings.ReplaceInt32(key, value); + else + fSettings.AddInt32(key, value); +} + + +bool +DriverSpecificSettings::HasDouble(const char* key) const +{ + double value; + return fSettings.FindDouble(key, &value) == B_OK; +} + + +double +DriverSpecificSettings::GetDouble(const char* key) const +{ + ASSERT(HasDouble(key)); + double value; + fSettings.FindDouble(key, &value); + return value; +} + + +void +DriverSpecificSettings::SetDouble(const char* key, double value) +{ + if (HasDouble(key)) + fSettings.ReplaceDouble(key, value); + else + fSettings.AddDouble(key, value); +} + + +BMessage& +DriverSpecificSettings::Message() +{ + return fSettings; +} + + +JobData::JobData(BMessage *msg, const PrinterCap *cap, SettingType type) +{ + load(msg, cap, type); } @@ -91,7 +237,7 @@ JobData::operator=(const JobData &job_data) fPrintStyle = job_data.fPrintStyle; fBindingLocation = job_data.fBindingLocation; fPageOrder = job_data.fPageOrder; - fSettings = job_data.fSettings; + fSettingType = job_data.fSettingType; fMsg = job_data.fMsg; fColor = job_data.fColor; fDitherType = job_data.fDitherType; @@ -105,10 +251,10 @@ JobData::operator=(const JobData &job_data) void -JobData::load(BMessage *msg, const PrinterCap *cap, Settings settings) +JobData::load(BMessage *msg, const PrinterCap *cap, SettingType type) { fMsg = msg; - fSettings = settings; + fSettingType = type; const PaperCap *paperCap = NULL; @@ -297,10 +443,9 @@ JobData::load(BMessage *msg, const PrinterCap *cap, Settings settings) else fMarginUnit = kUnitInch; - BString serializedSettings; - if (msg->HasString(kJDDriverSpecificSettings)) - msg->FindString(kJDDriverSpecificSettings, &serializedSettings); - DeserializePrinterSpecificSettings(serializedSettings); + if (msg->HasMessage(kJDDriverSpecificSettings)) + msg->FindMessage(kJDDriverSpecificSettings, + &fDriverSpecificSettings.Message()); } @@ -357,139 +502,87 @@ JobData::save(BMessage *msg) // make sure job settings are not present in page settings msg->RemoveName(kJDShowPreview); - if (fSettings == kJobSettings) + if (fSettingType == kJobSettings) msg->AddBool(kJDShowPreview, fShowPreview); msg->RemoveName(kJDNup); - if (fSettings == kJobSettings) + if (fSettingType == kJobSettings) msg->AddInt32(kJDNup, fNup); msg->RemoveName(kJDFirstPage); - if (fSettings == kJobSettings) + if (fSettingType == kJobSettings) msg->AddInt32(kJDFirstPage, fFirstPage); msg->RemoveName(kJDLastPage); - if (fSettings == kJobSettings) + if (fSettingType == kJobSettings) msg->AddInt32(kJDLastPage, fLastPage); msg->RemoveName(kJDGamma); - if (fSettings == kJobSettings) + if (fSettingType == kJobSettings) msg->AddFloat(kJDGamma, fGamma); msg->RemoveName(kJDInkDensity); - if (fSettings == kJobSettings) + if (fSettingType == kJobSettings) msg->AddFloat(kJDInkDensity, fInkDensity); msg->RemoveName(kJDPaperSource); - if (fSettings == kJobSettings) + if (fSettingType == kJobSettings) msg->AddInt32(kJDPaperSource, fPaperSource); msg->RemoveName(kJDCopies); - if (fSettings == kJobSettings) + if (fSettingType == kJobSettings) msg->AddInt32(kJDCopies, fCopies); msg->RemoveName(kJDCollate); - if (fSettings == kJobSettings) + if (fSettingType == kJobSettings) msg->AddBool(kJDCollate, fCollate); msg->RemoveName(kJDReverse); - if (fSettings == kJobSettings) + if (fSettingType == kJobSettings) msg->AddBool(kJDReverse, fReverse); msg->RemoveName(kJDPrintStyle); - if (fSettings == kJobSettings) + if (fSettingType == kJobSettings) msg->AddInt32(kJDPrintStyle, fPrintStyle); msg->RemoveName(kJDBindingLocation); - if (fSettings == kJobSettings) + if (fSettingType == kJobSettings) msg->AddInt32(kJDBindingLocation, fBindingLocation); msg->RemoveName(kJDPageOrder); - if (fSettings == kJobSettings) + if (fSettingType == kJobSettings) msg->AddInt32(kJDPageOrder, fPageOrder); msg->RemoveName(kJDColor); - if (fSettings == kJobSettings) + if (fSettingType == kJobSettings) msg->AddInt32(kJDColor, fColor); msg->RemoveName(kJDDitherType); - if (fSettings == kJobSettings) + if (fSettingType == kJobSettings) msg->AddInt32(kJDDitherType, fDitherType); msg->RemoveName(kJDPageSelection); - if (fSettings == kJobSettings) + if (fSettingType == kJobSettings) msg->AddInt32(kJDPageSelection, fPageSelection); msg->RemoveName(kJDDriverSpecificSettings); - if (fSettings == kJobSettings) + if (fSettingType == kJobSettings) { - BString serializedSettings; - SerializePrinterSpecificSettings(serializedSettings); - msg->AddString(kJDDriverSpecificSettings, serializedSettings); + msg->AddMessage(kJDDriverSpecificSettings, + &fDriverSpecificSettings.Message()); } } -bool -JobData::HasDriverSpecificSetting(const string& category) const +DriverSpecificSettings& +JobData::Settings() { - return fDriverSpecificSettings.find(category) != - fDriverSpecificSettings.end(); + return fDriverSpecificSettings; } -const string& -JobData::DriverSpecificSetting(const string& category) const +const DriverSpecificSettings& +JobData::Settings() const { - return fDriverSpecificSettings.find(category)->second; -} - - -void -JobData::SetDriverSpecificSetting(const string& category, const string& value) -{ - fDriverSpecificSettings[category] = value; -} - - -void -JobData::SerializePrinterSpecificSettings(BString& serializedSettings) -{ - bool first = true; - map::iterator it = fDriverSpecificSettings.begin(); - for (; it != fDriverSpecificSettings.end(); it++) { - if (first) - first = false; - else - serializedSettings << kDriverSpecificSettingsSeparator; - - serializedSettings << it->first.c_str() - << kDriverSpecificSettingsSeparator - << it->second.c_str(); - } -} - - -void -JobData::DeserializePrinterSpecificSettings(BString& serializedSettings) -{ - // Note: strtok_r terminates the string after the first token - fDriverSpecificSettings.clear(); - - int length = serializedSettings.Length() + 1; - char* state = NULL; - char* buffer = serializedSettings.LockBuffer(length); - const char* separator = kDriverSpecificSettingsSeparator; - char* token = strtok_r(buffer, separator, &state); - while (token != NULL) { - char* key = token; - token = strtok_r(NULL, separator, &state); - if (token == NULL) - break; - char* value = token; - fDriverSpecificSettings[key] = value; - token = strtok_r(NULL, separator, &state); - } - - serializedSettings.UnlockBuffer(0); + return fDriverSpecificSettings; } diff --git a/src/libs/print/libprint/JobSetupDlg.cpp b/src/libs/print/libprint/JobSetupDlg.cpp index b8806275c4..54b4279d74 100644 --- a/src/libs/print/libprint/JobSetupDlg.cpp +++ b/src/libs/print/libprint/JobSetupDlg.cpp @@ -50,10 +50,10 @@ using namespace std; -struct NupCap : public BaseCap { +struct NupCap : public EnumCap { NupCap(const string &label, bool isDefault, int nup) : - BaseCap(label, isDefault), + EnumCap(label, isDefault), fNup(nup) {} @@ -63,11 +63,11 @@ struct NupCap : public BaseCap { }; -struct DitherCap : public BaseCap { +struct DitherCap : public EnumCap { DitherCap(const string &label, bool isDefault, Halftone::DitherType ditherType) : - BaseCap(label, isDefault), + EnumCap(label, isDefault), fDitherType(ditherType) {} @@ -116,6 +116,9 @@ const BaseCap *gDitherTypes[] = { }; +static const char* kCategoryID = "id"; + + enum { kMsgRangeAll = 'JSdl', kMsgRangeSelection, @@ -125,10 +128,18 @@ enum { kMsgCollateChanged, kMsgReverseChanged, kMsgDuplexChanged, + kMsgIntSliderChanged, + kMsgDoubleSliderChanged, kMsgNone = 0 }; +BString& operator<<(BString& text, double value) +{ + text << (float)value; + return text; +} + JobSetupView::JobSetupView(JobData* jobData, PrinterData* printerData, const PrinterCap *printerCap) : @@ -256,8 +267,8 @@ JobSetupView::AttachedToWindow() // Pages per sheet fNup = new BPopUpMenu(""); fNup->SetRadioMode(true); - FillCapabilityMenu(fNup, kMsgNone, gNups, sizeof(gNups) / sizeof(gNups[0]), - (int)fJobData->getNup()); + FillCapabilityMenu(fNup, kMsgNone, gNups, + sizeof(gNups) / sizeof(gNups[0]), (int)fJobData->getNup()); BMenuField* pagesPerSheet = new BMenuField("pagesPerSheet", "Pages Per Sheet:", fNup); @@ -356,6 +367,14 @@ JobSetupView::AttachedToWindow() qualityGridLayout->SetSpacing(0, 0); qualityGridLayout->SetInsets(5, 5, 5, 5); qualityBox->AddChild(qualityGrid); + // TODO put qualityGrid in a scroll view + // the layout of the box surrounding the scroll view using the following + // code is not correct; the box still has the size of the qualityGird; + // and the scroll view is vertically centered inside the box! + //BScrollView* qualityScroller = new BScrollView("qualityScroller", + // qualityGrid, 0, false, true); + //qualityScroller->SetExplicitMaxSize(BSize(500, 500)); + //qualityBox->AddChild(qualityScroller); BGridView* pageRangeGrid = new BGridView(); BGridLayout* pageRangeLayout = pageRangeGrid->GridLayout(); @@ -503,51 +522,186 @@ JobSetupView::AddDriverSpecificSettings(BGridLayout* gridLayout, int row) PrinterCap::kDriverSpecificCapabilities); for (int i = 0; i < count; i ++) { - const DriverSpecificCap* capability = static_cast( - capabilities[i]); + const DriverSpecificCap* capability = + static_cast(capabilities[i]); - const char* label = capability->fLabel.c_str(); - BPopUpMenu* popUpMenu = new BPopUpMenu(label); - popUpMenu->SetRadioMode(true); + switch (capability->fType) { + case DriverSpecificCap::kList: + AddPopUpMenu(capability, gridLayout, row); + break; + case DriverSpecificCap::kBoolean: + AddCheckBox(capability, gridLayout, row); + break; + case DriverSpecificCap::kIntRange: + case DriverSpecificCap::kIntDimension: + AddIntSlider(capability, gridLayout, row); + break; + case DriverSpecificCap::kDoubleRange: + AddDoubleSlider(capability, gridLayout, row); + break; - PrinterCap::CapID category = static_cast( - capability->ID()); - - const BaseCap** categoryCapabilities = fPrinterCap->enumCap(category); - - int categoryCount = fPrinterCap->countCap(category); - - string value = GetDriverSpecificValue(category, capability->Key()); - PrinterCap::KeyPredicate predicate(value.c_str()); - - FillCapabilityMenu(popUpMenu, kMsgNone, categoryCapabilities, - categoryCount, predicate); - - BString menuLabel = label; - menuLabel << ":"; - BMenuField* menuField = new BMenuField(label, menuLabel.String(), - popUpMenu); - popUpMenu->SetTargetForItems(this); - - gridLayout->AddItem(menuField->CreateLabelLayoutItem(), - 0, row); - gridLayout->AddItem(menuField->CreateMenuBarLayoutItem(), - 1, row); - row ++; - - fDriverSpecificLists[category] = popUpMenu; + } } } +void +JobSetupView::AddPopUpMenu(const DriverSpecificCap* capability, + BGridLayout* gridLayout, int& row) +{ + const char* label = capability->fLabel.c_str(); + BPopUpMenu* popUpMenu = new BPopUpMenu(label); + popUpMenu->SetRadioMode(true); + + PrinterCap::CapID category = static_cast( + capability->ID()); + + const BaseCap** categoryCapabilities = fPrinterCap->enumCap(category); + + int categoryCount = fPrinterCap->countCap(category); + + string value = GetDriverSpecificValue(category, capability->Key()); + PrinterCap::KeyPredicate predicate(value.c_str()); + + FillCapabilityMenu(popUpMenu, kMsgNone, categoryCapabilities, + categoryCount, predicate); + + BString menuLabel = label; + menuLabel << ":"; + BMenuField* menuField = new BMenuField(label, menuLabel.String(), + popUpMenu); + popUpMenu->SetTargetForItems(this); + + gridLayout->AddItem(menuField->CreateLabelLayoutItem(), + 0, row); + gridLayout->AddItem(menuField->CreateMenuBarLayoutItem(), + 1, row); + row ++; + + fDriverSpecificPopUpMenus[category] = popUpMenu; +} + + +void +JobSetupView::AddCheckBox(const DriverSpecificCap* capability, + BGridLayout* gridLayout, int& row) +{ + PrinterCap::CapID category = static_cast( + capability->ID()); + const BooleanCap* booleanCap = fPrinterCap->findBooleanCap(category); + if (booleanCap == NULL) { + fprintf(stderr, "Internal error: BooleanCap for '%s' not found!\n", + capability->Label()); + return; + } + + const char* key = capability->Key(); + BString name; + name << "pds_" << key; + BCheckBox* checkBox = new BCheckBox(name.String(), capability->Label(), + NULL); + + bool value = booleanCap->DefaultValue(); + if (fJobData->Settings().HasBoolean(key)) + value = fJobData->Settings().GetBoolean(key); + if (value) + checkBox->SetValue(B_CONTROL_ON); + + gridLayout->AddView(checkBox, 0, row, 2); + row ++; + + fDriverSpecificCheckBoxes[capability->Key()] = checkBox; +} + + +void +JobSetupView::AddIntSlider(const DriverSpecificCap* capability, + BGridLayout* gridLayout, int& row) +{ + PrinterCap::CapID category = static_cast( + capability->ID()); + const IntRangeCap* range = fPrinterCap->findIntRangeCap(category); + if (range == NULL) { + fprintf(stderr, "Internal error: IntRangeCap for '%s' not found!\n", + capability->Label()); + return; + } + + const char* label = capability->Label(); + const char* key = capability->Key(); + BString name; + name << "pds_" << key; + BMessage* message = new BMessage(kMsgIntSliderChanged); + message->AddInt32(kCategoryID, category); + BSlider* slider = new BSlider(name.String(), label, + message, 0, 1000, B_HORIZONTAL); + slider->SetModificationMessage(new BMessage(*message)); + slider->SetTarget(this); + + int32 value = range->DefaultValue(); + if (fJobData->Settings().HasInt(key)) + value = fJobData->Settings().GetInt(key); + float position = (value - range->Lower()) / + (range->Upper() - range->Lower()); + slider->SetPosition(position); + + gridLayout->AddView(slider, 0, row, 2); + row ++; + + IntRange intRange(label, key, range, slider); + fDriverSpecificIntSliders[category] = intRange; + intRange.UpdateLabel(); +} + + +void +JobSetupView::AddDoubleSlider(const DriverSpecificCap* capability, + BGridLayout* gridLayout, int& row) +{ + PrinterCap::CapID category = static_cast( + capability->ID()); + const DoubleRangeCap* range = fPrinterCap->findDoubleRangeCap(category); + if (range == NULL) { + fprintf(stderr, "Internal error: DoubleRangeCap for '%s' not found!\n", + capability->Label()); + return; + } + + const char* label = capability->Label(); + const char* key = capability->Key(); + BString name; + name << "pds_" << key; + BMessage* message = new BMessage(kMsgDoubleSliderChanged); + message->AddInt32(kCategoryID, category); + BSlider* slider = new BSlider(name.String(), label, + message, 0, 1000, B_HORIZONTAL); + slider->SetModificationMessage(new BMessage(*message)); + slider->SetTarget(this); + + double value = range->DefaultValue(); + if (fJobData->Settings().HasDouble(key)) + value = fJobData->Settings().GetDouble(key); + float position = static_cast((value - range->Lower()) / + (range->Upper() - range->Lower())); + slider->SetPosition(position); + + gridLayout->AddView(slider, 0, row, 2); + row ++; + + DoubleRange doubleRange(label, key, range, slider); + fDriverSpecificDoubleSliders[category] = doubleRange; + doubleRange.UpdateLabel(); +} + + string JobSetupView::GetDriverSpecificValue(PrinterCap::CapID category, const char* key) { - if (fJobData->HasDriverSpecificSetting(key)) - return fJobData->DriverSpecificSetting(key); + if (fJobData->Settings().HasString(key)) + return fJobData->Settings().GetString(key); - const BaseCap* defaultCapability = fPrinterCap->getDefaultCap(category); + const EnumCap* defaultCapability = fPrinterCap->getDefaultCap(category); return defaultCapability->fKey; } @@ -563,7 +717,7 @@ JobSetupView::FillCapabilityMenu(BPopUpMenu* menu, uint32 message, BMenuItem* defaultItem = NULL; BMenuItem* item = NULL; while (count--) { - const BaseCap* capability = *capabilities; + const EnumCap* capability = dynamic_cast(*capabilities); if (message != kMsgNone) item = new BMenuItem(capability->fLabel.c_str(), new BMessage(message)); @@ -622,7 +776,11 @@ JobSetupView::GetID(const BaseCap** capabilities, int count, const char* label, int defaultValue) { while (count--) { - const BaseCap* capability = *capabilities; + const EnumCap* capability = + dynamic_cast(*capabilities); + if (capability == NULL) + break; + if (capability->fLabel == label) return capability->ID(); } @@ -665,7 +823,15 @@ JobSetupView::MessageReceived(BMessage* message) case kMsgReverseChanged: fPages->setReverse(fReverse->Value() == B_CONTROL_ON); - break; + break; + + case kMsgIntSliderChanged: + UpdateIntSlider(message); + break; + + case kMsgDoubleSliderChanged: + UpdateDoubleSlider(message); + break; } } @@ -681,6 +847,28 @@ JobSetupView::UpdateHalftonePreview() } +void +JobSetupView::UpdateIntSlider(BMessage* message) +{ + int32 id; + if (message->FindInt32(kCategoryID, &id) != B_OK) + return; + PrinterCap::CapID capID = static_cast(id); + fDriverSpecificIntSliders[capID].UpdateLabel(); +} + + +void +JobSetupView::UpdateDoubleSlider(BMessage* message) +{ + int32 id; + if (message->FindInt32(kCategoryID, &id) != B_OK) + return; + PrinterCap::CapID capID = static_cast(id); + fDriverSpecificDoubleSliders[capID].UpdateLabel(); +} + + JobData::Color JobSetupView::Color() { @@ -779,16 +967,48 @@ JobSetupView::UpdateJobData() pageSelection = JobData::kEvenNumberedPages; fJobData->setPageSelection(pageSelection); - std::map::iterator it = - fDriverSpecificLists.begin(); - for(; it != fDriverSpecificLists.end(); it++) { - PrinterCap::CapID category = it->first; - BPopUpMenu* popUpMenu = it->second; - const char* key = fPrinterCap->findCap( - PrinterCap::kDriverSpecificCapabilities, (int)category)->Key(); - const char* label = popUpMenu->FindMarked()->Label(); - const char* value = fPrinterCap->findCap(category, label)->Key(); - fJobData->SetDriverSpecificSetting(key, value); + { + std::map::iterator it = + fDriverSpecificPopUpMenus.begin(); + for(; it != fDriverSpecificPopUpMenus.end(); it++) { + PrinterCap::CapID category = it->first; + BPopUpMenu* popUpMenu = it->second; + const char* key = fPrinterCap->findCap( + PrinterCap::kDriverSpecificCapabilities, (int)category)->Key(); + const char* label = popUpMenu->FindMarked()->Label(); + const char* value = static_cast(fPrinterCap-> + findCap(category, label))->Key(); + fJobData->Settings().SetString(key, value); + } + } + + { + std::map::iterator it = + fDriverSpecificCheckBoxes.begin(); + for(; it != fDriverSpecificCheckBoxes.end(); it++) { + const char* key = it->first.c_str(); + BCheckBox* checkBox = it->second; + bool value = checkBox->Value() == B_CONTROL_ON; + fJobData->Settings().SetBoolean(key, value); + } + } + + { + std::map::iterator it = + fDriverSpecificIntSliders.begin(); + for(; it != fDriverSpecificIntSliders.end(); it++) { + IntRange& range = it->second; + fJobData->Settings().SetInt(range.Key(), range.Value()); + } + } + + { + std::map::iterator it = + fDriverSpecificDoubleSliders.begin(); + for(; it != fDriverSpecificDoubleSliders.end(); it++) { + DoubleRange& range = it->second; + fJobData->Settings().SetDouble(range.Key(), range.Value()); + } } fJobData->save(); diff --git a/src/libs/print/libprint/PrinterCap.cpp b/src/libs/print/libprint/PrinterCap.cpp index ca35cef653..c307063c34 100644 --- a/src/libs/print/libprint/PrinterCap.cpp +++ b/src/libs/print/libprint/PrinterCap.cpp @@ -6,10 +6,9 @@ #include "PrinterCap.h" #include "PrinterData.h" -BaseCap::BaseCap(const string &label, bool isDefault) +BaseCap::BaseCap(const string &label) : - fLabel(label), - fIsDefault(isDefault) + fLabel(label) { } @@ -20,7 +19,22 @@ BaseCap::~BaseCap() const char* -BaseCap::Key() const +BaseCap::Label() const +{ + return fLabel.c_str(); +} + + +EnumCap::EnumCap(const string &label, bool isDefault) + : + BaseCap(label), + fIsDefault(isDefault) +{ +} + + +const char* +EnumCap::Key() const { return fKey.c_str(); } @@ -29,7 +43,7 @@ BaseCap::Key() const PaperCap::PaperCap(const string &label, bool isDefault, JobData::Paper paper, const BRect &paperRect, const BRect &physicalRect) : - BaseCap(label, isDefault), + EnumCap(label, isDefault), fPaper(paper), fPaperRect(paperRect), fPhysicalRect(physicalRect) @@ -47,7 +61,7 @@ PaperCap::ID() const PaperSourceCap::PaperSourceCap(const string &label, bool isDefault, JobData::PaperSource paperSource) : - BaseCap(label, isDefault), + EnumCap(label, isDefault), fPaperSource(paperSource) { } @@ -63,7 +77,7 @@ PaperSourceCap::ID() const ResolutionCap::ResolutionCap(const string &label, bool isDefault, int32 id, int xResolution, int yResolution) : - BaseCap(label, isDefault), + EnumCap(label, isDefault), fID(id), fXResolution(xResolution), fYResolution(yResolution) @@ -81,7 +95,7 @@ ResolutionCap::ID() const OrientationCap::OrientationCap(const string &label, bool isDefault, JobData::Orientation orientation) : - BaseCap(label, isDefault), + EnumCap(label, isDefault), fOrientation(orientation) { } @@ -97,7 +111,7 @@ OrientationCap::ID() const PrintStyleCap::PrintStyleCap(const string &label, bool isDefault, JobData::PrintStyle printStyle) : - BaseCap(label, isDefault), + EnumCap(label, isDefault), fPrintStyle(printStyle) { } @@ -113,7 +127,7 @@ PrintStyleCap::ID() const BindingLocationCap::BindingLocationCap(const string &label, bool isDefault, JobData::BindingLocation bindingLocation) : - BaseCap(label, isDefault), + EnumCap(label, isDefault), fBindingLocation(bindingLocation) { } @@ -128,7 +142,7 @@ BindingLocationCap::ID() const ColorCap::ColorCap(const string &label, bool isDefault, JobData::Color color) : - BaseCap(label, isDefault), + EnumCap(label, isDefault), fColor(color) { } @@ -144,7 +158,7 @@ ColorCap::ID() const ProtocolClassCap::ProtocolClassCap(const string &label, bool isDefault, int32 protocolClass, const string &description) : - BaseCap(label, isDefault), + EnumCap(label, isDefault), fProtocolClass(protocolClass), fDescription(description) { @@ -161,7 +175,7 @@ ProtocolClassCap::ID() const DriverSpecificCap::DriverSpecificCap(const string& label, int32 category, Type type) : - BaseCap(label, false), + EnumCap(label, false), fCategory(category), fType(type) { @@ -177,7 +191,7 @@ DriverSpecificCap::ID() const ListItemCap::ListItemCap(const string& label, bool isDefault, int32 id) : - BaseCap(label, isDefault), + EnumCap(label, isDefault), fID(id) { } @@ -190,6 +204,85 @@ ListItemCap::ID() const } +BooleanCap::BooleanCap(const string& label, bool defaultValue) + : + BaseCap(label), + fDefaultValue(defaultValue) +{ +} + + +bool +BooleanCap::DefaultValue() const +{ + return fDefaultValue; +} + + +IntRangeCap::IntRangeCap(const string& label, int lower, int upper, + int defaultValue) + : + BaseCap(label), + fLower(lower), + fUpper(upper), + fDefaultValue(defaultValue) +{ +} + + +int32 +IntRangeCap::Lower() const +{ + return fLower; +} + + +int32 +IntRangeCap::Upper() const +{ + return fUpper; +} + + +int32 +IntRangeCap::DefaultValue() const +{ + return fDefaultValue; +} + + +DoubleRangeCap::DoubleRangeCap(const string& label, double lower, double upper, + double defaultValue) + : + BaseCap(label), + fLower(lower), + fUpper(upper), + fDefaultValue(defaultValue) +{ +} + + +double +DoubleRangeCap::Lower() const +{ + return fLower; +} + + +double +DoubleRangeCap::Upper() const +{ + return fUpper; +} + + +double +DoubleRangeCap::DefaultValue() const +{ + return fDefaultValue; +} + + PrinterCap::PrinterCap(const PrinterData *printer_data) : fPrinterData(printer_data) @@ -202,7 +295,7 @@ PrinterCap::~PrinterCap() } -const BaseCap* +const EnumCap* PrinterCap::getDefaultCap(CapID category) const { int count = countCap(category); @@ -211,13 +304,18 @@ PrinterCap::getDefaultCap(CapID category) const const BaseCap **base_cap = enumCap(category); while (count--) { - if ((*base_cap)->fIsDefault) { - return *base_cap; + const EnumCap* enumCap = dynamic_cast(*base_cap); + if (enumCap == NULL) + return NULL; + + if (enumCap->fIsDefault) { + return enumCap; } + base_cap++; } - return enumCap(category)[0]; + return static_cast(enumCap(category)[0]); } @@ -240,11 +338,11 @@ PrinterCap::findCap(CapID category, Predicate& predicate) const } -const BaseCap* +const EnumCap* PrinterCap::findCap(CapID category, int id) const { IDPredicate predicate(id); - return findCap(category, predicate); + return static_cast(findCap(category, predicate)); } @@ -256,11 +354,38 @@ PrinterCap::findCap(CapID category, const char* label) const } -const BaseCap* +const EnumCap* PrinterCap::findCapWithKey(CapID category, const char* key) const { KeyPredicate predicate(key); - return findCap(category, predicate); + return static_cast(findCap(category, predicate)); +} + + +const BooleanCap* +PrinterCap::findBooleanCap(CapID category) const +{ + if (countCap(category) != 1) + return NULL; + return dynamic_cast(enumCap(category)[0]); +} + + +const IntRangeCap* +PrinterCap::findIntRangeCap(CapID category) const +{ + if (countCap(category) != 1) + return NULL; + return dynamic_cast(enumCap(category)[0]); +} + + +const DoubleRangeCap* +PrinterCap::findDoubleRangeCap(CapID category) const +{ + if (countCap(category) != 1) + return NULL; + return dynamic_cast(enumCap(category)[0]); }