class Row2(Row): columns = [ ColumnSpec(LineEditColumn, key_name="brand", label_name="Brand"), ColumnSpec(LineEditColumn, key_name="year", label_name="Year") ]
class TestRow(Row): columns = [ ColumnSpec(LineEditColumn, key_name="firstname", label_name="First Name"), ColumnSpec(LineEditColumn, key_name="surname", label_name="Surname"), ColumnSpec(LineEditColumn, key_name="address", label_name="Address") ]
class Row1(Row): columns = [ ColumnSpec(LineEditColumn, key_name="name", label_name="First Name"), ColumnSpec(LineEditColumn, key_name="surname", label_name="Last Name") ]
class PersonRow(Row): # Reduce the schema columns = [ ColumnSpec(LineEditColumn, key_name="firstname", label_name="First Name"), ColumnSpec(LineEditColumn, key_name="surname", label_name="Surname") ]
class FoodRow(Row): columns = [ ColumnSpec(LineEditColumn, key_name="name", label_name="Name"), ColumnSpec(LineEditColumn, key_name="price", label_name="Price"), ColumnSpec(CheckBoxColumn, key_name="spicy", label_name="Is spicy") ]
class DeviceRow(Row): columns = [ ColumnSpec(LineEditColumn, key_name="url", label_name="URL"), ColumnSpec(LineEditColumn, key_name="user", label_name="User"), ColumnSpec(LineEditColumn, key_name="password", label_name="Password"), ColumnSpec(LineEditColumn, key_name="description", label_name="Description") ]
class USBCameraRow(Row): name = "H264 USB Camera" columns = [ ColumnSpec(ConstantIntegerColumn, key_name="slot", label_name="Slot"), ColumnSpec(USBCameraColumn, key_name="address", label_name="Device") ] def isActive(self): """Show only if there are USB cams """ return len(tools.getH264V4l2()) > 0
class LinkRow(Row): columns = [ ColumnSpec(ForeignKeyColumn, key_name="user_key"), ColumnSpec(ForeignKeyColumn, key_name="car_key"), ColumnSpec(CheckBoxColumn, key_name="drive", label_name="Can drive"), ColumnSpec(CheckBoxColumn, key_name="sell", label_name="Can sell") ]
class PersonRowExtended(Row): columns = [ ColumnSpec(LineEditColumn, key_name="firstname", label_name="First Name"), ColumnSpec(LineEditColumn, key_name="secondname", label_name="Second Name"), ColumnSpec(LineEditColumn, key_name="surname", label_name="Surname"), ColumnSpec(LineEditColumn, key_name="address", label_name="Address") ]
class SDPFileRow(Row): name = "SDP File" columns = [ ColumnSpec(ConstantIntegerColumn, key_name="slot", label_name="Slot"), ColumnSpec(FileDialogColumn, key_name="address", label_name="SDP File", filter="*.sdp") ] def isActive(self): return True
class AreaRightsPerCompanyRow(Row): columns = [ ColumnSpec(ForeignKeyColumn, key_name="company_id", collection=self.company_collection), ColumnSpec(ForeignKeyColumn, key_name="area_id", collection=self.area_collection), ColumnSpec(LineEditColumn, key_name="max", label_name="Max. vehicles") ]
class FoodRow(Row): # Extend the schema columns = [ ColumnSpec(LineEditColumn, key_name="name", label_name="Name"), ColumnSpec(LineEditColumn, key_name="price", label_name="Price"), ColumnSpec(CheckBoxColumn, key_name="spicy", label_name="Is spicy"), ColumnSpec(CheckBoxColumn, key_name="healthy", label_name="Is Healty") ]
class PersonRow(Row): columns = [ ColumnSpec(LineEditColumn, key_name="name", label_name="Name"), ColumnSpec(LineEditColumn, key_name="surname", label_name="Surname"), ColumnSpec(LineEditColumn, key_name="phone", label_name="Phone Number"), ColumnSpec(LineEditColumn, key_name="email", label_name="E-mail") ]
class AreaRightsRow(Row): columns = [ ColumnSpec(ForeignKeyColumn, key_name="vehicle_id", collection=self.vehicle_collection), ColumnSpec(ForeignKeyColumn, key_name="area_id", collection=self.area_collection), ColumnSpec(CheckBoxColumn, key_name="morning", label_name="Can park in the morning"), ColumnSpec(CheckBoxColumn, key_name="evening", label_name="Can park in the evening") ]
class PersonRow(Row): columns = [ ColumnSpec(LineEditColumn, key_name="firstname", label_name="First Name"), ColumnSpec(LineEditColumn, key_name="surname", label_name="Surname"), ColumnSpec(LineEditColumn, key_name="address", label_name="Address"), ColumnSpec(CheckBoxColumn, key_name="married", label_name="Is married") ]
class LayoutContainerRow(Row): name = "LayoutContainer" columns = [ ColumnSpec( Column, # just a list of json objects :) key_name="layout"), ]
class VehicleRow(Row): columns = [ ColumnSpec(LineEditColumn, key_name="license_plate", label_name="License Plate"), ColumnSpec(LineEditColumn, key_name="brand", label_name="Brand"), ColumnSpec(LineEditColumn, key_name="color", label_name="Color"), ColumnSpec(ForeignKeyColumn, key_name="person_id", collection=self.person_collection), ColumnSpec(ForeignKeyColumn, key_name="company_id", collection=self.company_collection) ]
class EmptyRow(Row): name = "<Empty>" columns = [ ColumnSpec(ConstantIntegerColumn, key_name="slot", label_name="Slot"), ] def isActive(self): """Is this row class visible in the form drop-down menu """ return True
class PersonRowExtended(Row): columns = [ ColumnSpec(LineEditColumn, key_name="firstname", label_name="First Name"), ColumnSpec(LineEditColumn, key_name="secondname", label_name="Second Name"), ColumnSpec(LineEditColumn, key_name="surname", label_name="Surname"), ColumnSpec(LineEditColumn, key_name="address", label_name="Address"), # in the following, we're referring to self.food_collection and there, to the columns with keys "_id" and "name". The ListEditColumn itself is a list of foreign_keys ColumnSpec(ListEditColumn, key_name="foods", label_name="Favorite foods", collection=self.food_collection, foreign_label_name="name") ]
class AreaRow(Row): columns = [ ColumnSpec(LineEditColumn, key_name="name", label_name="Name"), ColumnSpec(LineEditColumn, key_name="description", label_name="Description"), ColumnSpec(ListEditColumn, key_name="incoming", label_name="Cameras IN", collection=self.device_collection, foreign_label_name="url"), ColumnSpec(ListEditColumn, key_name="outgoing", label_name="Cameras OUT", collection=self.device_collection, foreign_label_name="url"), ColumnSpec(LineEditColumn, key_name="max", label_name="Max. vehicles"), ColumnSpec(ListEditColumn, key_name="parked", label_name="Currently parked", collection=self.vehicle_collection, foreign_label_name="license_plate") ]
class TestRow_(Row): columns = [ ColumnSpec(LineEditColumn, key_name="firstname", label_name="First Name"), ColumnSpec(LineEditColumn, key_name="secondname", label_name="Second Name"), ColumnSpec(LineEditColumn, key_name="surname", label_name="Surname"), ColumnSpec(ComboBoxColumn, key_name="address", label_name="Address", collection=self.side_collection, foreign_label_name="address"), ColumnSpec(ConstantComboBoxColumn, key_name="device", label_name="Device", callback=get_devices), ColumnSpec(ConstantRadioButtonColumn, key_name="multichoice", label_name=mc_label, list=multichoice) # foreigh_label_name = which key is taken for the drop-down list ]
class MemoryConfigRow(Row): # A general collection for misc. stuff: configuration, etc. columns = [ ColumnSpec(IntegerColumn, key_name="msbuftime", label_name="Buffering time (ms)", min_value=50, max_value=1000, def_value=default.get_memory_config()["msbuftime"]), ColumnSpec(IntegerColumn, key_name="n_720p", label_name="Number of 720p streams", min_value=0, max_value=1024, def_value=default.get_memory_config()["n_720p"]), ColumnSpec(IntegerColumn, key_name="n_1080p", label_name="Number of 1080p streams", min_value=0, max_value=1024, def_value=default.get_memory_config()["n_1080p"]), ColumnSpec(IntegerColumn, key_name="n_1440p", label_name="Number of 2K streams", min_value=0, max_value=1024, def_value=default.get_memory_config()["n_1440p"]), ColumnSpec(IntegerColumn, key_name="n_4K", label_name="Number of 4K streams", min_value=0, max_value=1024, def_value=default.get_memory_config()["n_4K"]), ColumnSpec(CheckBoxColumn, key_name="bind", label_name="Bind decoding thread to single core", def_value=default.get_memory_config()["bind"]), ColumnSpec( CheckBoxColumn, key_name="overwrite_timestamps", label_name="Overwrite timestamps", def_value=default.get_memory_config()["overwrite_timestamps"]) ] def getNFrames(self, key): """Get number of necessary frames for certain camera resolution :param key: n720p, n1080p, etc. """ buftime = self["buftime"] ncam = self[key] # assume 25 fps cameras return int((buftime / 1000) * 25 * ncam)
class MemoryConfigRow(Row): columns = [ ColumnSpec(IntegerColumn, key_name="msbuftime", label_name="Buffering time (ms)", min_value=50, max_value=1000, def_value=default.memory_config["msbuftime"]), ColumnSpec(IntegerColumn, key_name="n_720p", label_name="Number of 720p streams", min_value=0, max_value=1024, def_value=default.memory_config["n_720p"]), ColumnSpec(IntegerColumn, key_name="n_1080p", label_name="Number of 1080p streams", min_value=0, max_value=1024, def_value=default.memory_config["n_1080p"]), ColumnSpec(IntegerColumn, key_name="n_1440p", label_name="Number of 2K streams", min_value=0, max_value=1024, def_value=default.memory_config["n_1440p"]), ColumnSpec(IntegerColumn, key_name="n_4K", label_name="Number of 4K streams", min_value=0, max_value=1024, def_value=default.memory_config["n_4K"]), ColumnSpec(CheckBoxColumn, key_name="bind", label_name="Bind Valkka threads to cores", def_value=default.memory_config["bind"]) ] def getNFrames(self, key): """Get number of necessary frames for certain camera resolution :param key: n720p, n1080p, etc. """ buftime = self["buftime"] ncam = self[key] # assume 25 fps cameras return int((buftime / 1000) * 25 * ncam)
class CompanyRow(Row): columns = [ ColumnSpec(LineEditColumn, key_name="name", label_name="Name") # could add here whatever company data.. address, phone number, etc. ]
class AddresRow(Row): columns = [ ColumnSpec(LineEditColumn, key_name="address", label_name="Address") ]
class RTSPCameraRow(Row): name = "RTSP Camera" columns = [ ColumnSpec(ConstantIntegerColumn, key_name="slot", label_name="Slot"), ColumnSpec(IPv4AddressColumn, key_name="address", label_name="IP Address"), ColumnSpec(LineEditColumn, key_name="username", label_name="Username"), ColumnSpec(LineEditColumn, key_name="password", label_name="Password"), ColumnSpec(LineEditColumn, key_name="port", label_name="Port"), ColumnSpec(LineEditColumn, key_name="tail", label_name="Tail"), ColumnSpec(LineEditColumn, key_name="subaddress_main", label_name="Subaddress", visible=False), ColumnSpec(CheckBoxColumn, key_name="live_main", label_name="Use stream", def_value=True), ColumnSpec(CheckBoxColumn, key_name="rec_main", label_name="Record stream", def_value=False), ColumnSpec(LineEditColumn, key_name="subaddress_sub", label_name="Subaddress"), ColumnSpec(CheckBoxColumn, key_name="live_sub", label_name="Use stream", def_value=False), ColumnSpec(CheckBoxColumn, key_name="rec_sub", label_name="Record stream", def_value=False) ] def isActive(self): return True @classmethod def getMainAddressFromDict(cls, dic): st = "rtsp://" st += dic["username"] + ":" st += dic["password"] + "@" st += dic["address"] if (dic["port"].strip() != ""): st += ":" + dic["port"].strip() if (len(dic["tail"]) > 0): st += "/" + dic["tail"] if (len(dic["subaddress_main"]) > 0): st += "/" + dic["subaddress_main"] return st @classmethod def getSubAddressFromDict(cls, dic): st = "rtsp://" st += dic["username"] + ":" st += dic["password"] + "@" st += dic["address"] if (dic["port"].strip() != ""): st += ":" + dic["port"].strip() if (len(dic["tail"]) > 0): st += "/" + dic["tail"] if (len(dic["subaddress_main"]) > 0): st += "/" + dic["subaddress_sub"] return st def makeWidget(self): """Subclassed from Row : custom form. Add a summary RTSP address in the end of the form, etc. """ # super().makeWidget() # do all by hand self.widget = FormWidget() self.lay = QtWidgets.QGridLayout(self.widget) cc = 0 self.placeWidget(cc, "slot") cc += 1 self.placeWidget(cc, "address") cc += 1 self.placeWidget(cc, "username") cc += 1 self.placeWidget(cc, "password") cc += 1 self.placeWidget(cc, "port") cc += 1 self.placeWidget(cc, "tail") cc += 1 # self.setVisible("tail", False) # test # Mainstream self.label_mainstream = QtWidgets.QLabel("Mainstream", self.widget) self.label_mainstream.setStyleSheet(style.form_highlight) self.placeWidgetPair(cc, (self.label_mainstream, None)) cc += 1 self.placeWidget(cc, "subaddress_main") cc += 1 # complete RTSP address self.label_mainstream_address = QtWidgets.QLabel( "RTSP address", self.widget) self.mainstream_address = QtWidgets.QLabel("", self.widget) self.placeWidgetPair( cc, (self.label_mainstream_address, self.mainstream_address)) cc += 1 # live and rec self.placeWidget(cc, "live_main") cc += 1 self.placeWidget(cc, "rec_main") cc += 1 # Substream self.label_substream = QtWidgets.QLabel("Substream", self.widget) self.label_substream.setStyleSheet(style.form_highlight) self.placeWidgetPair(cc, (self.label_substream, None)) cc += 1 self.label_substream.setVisible(False) # hide for the moment self.placeWidget(cc, "subaddress_sub") cc += 1 # complete RTSP address self.label_substream_address = QtWidgets.QLabel( "RTSP address", self.widget) self.substream_address = QtWidgets.QLabel("", self.widget) self.placeWidgetPair( cc, (self.label_substream_address, self.substream_address)) cc += 1 self.label_substream_address.setVisible(False) self.substream_address.setVisible(False) # .. hide for the moment # live and rec self.placeWidget(cc, "live_sub") cc += 1 self.placeWidget(cc, "rec_sub") cc += 1 """ # definitely NOT here! # self.copy_label = QtWidgets.QLabel("Copy this camera", self.widget) self.copy_button = QtWidgets.QPushButton("Copy", self.widget) self.placeWidgetPair(cc, (self.copy_button, None)) self.copy_button.clicked.connect(self.copy_slot) """ self.connectNotifications() def rec_main_clicked(): if not self["live_main"].widget.isChecked(): # rec requires live print("live_main is NOT checked") self["rec_main"].widget.setChecked(False) if self["rec_main"].widget.isChecked( ): # rec main excludes rec sub self["rec_sub"].widget.setChecked(False) def rec_sub_clicked(): if not self["live_sub"].widget.isChecked(): # rec requires live print("live_sub is NOT checked") self["rec_sub"].widget.setChecked(False) if self["rec_sub"].widget.isChecked(): # rec sub excludes rec main self["rec_main"].widget.setChecked(False) self["rec_main"].widget.clicked.connect(rec_main_clicked) self["rec_sub"].widget.clicked.connect(rec_sub_clicked) self.widget.signals.show.connect(self.show_slot) # TODO: remove these restrictions once functional: """ self["subaddress_main"].widget.setEnabled(False) self["subaddress_sub"].widget.setEnabled(False) self["live_main"].widget.setEnabled(False) self["rec_main"].widget.setEnabled(False) self["live_sub"].widget.setEnabled(False) self["rec_sub"].widget.setEnabled(False) """ self.setVisible("subaddress_main", False) self.setVisible("subaddress_sub", False) self.setVisible("live_main", False) self.setVisible("rec_main", False) self.setVisible("live_sub", False) self.setVisible("rec_sub", False) """ def get(self, collection, _id): #Subclassed from Row : Load one entry from db to QtWidgets super().get(collection, _id) self.update_notify_slot() """ def getMainAddress(self): # e.g. : rtsp://admin:[email protected]/tail dic = self.__collect__() # returns a dictionary of column values return RTSPCameraRow.getMainAddressFromDict(dic) def getSubAddress(self): # e.g. : rtsp://admin:[email protected]/tail dic = self.__collect__() # returns a dictionary of column values return RTSPCameraRow.getSubAddressFromDict(dic) def update_notify_slot(self): """This slot gets pinged always when the form fields have been updated """ # pass # print("RTSPCameraRow: value changed") self.mainstream_address.setText(self.getMainAddress()) self.substream_address.setText(self.getSubAddress()) # self.copy_button.setEnabled(False) # must save before can copy # nopes .. # rec main and sub exclude each other # rec requires live def show_slot(self): self.mainstream_address.setText(self.getMainAddress()) self.substream_address.setText(self.getSubAddress())
class ValkkaFSConfigRow(Row): def getValkkaFSDevices(): lis = [] # tuples of (name, key) for key, value in findBlockDevices().items(): # they look like this: {'27f5e5d8-9e20-4bc1-84aa-6a3cbab498c8': ('/dev/sdc1', 500107862016)} lis.append(( value[0] + " (" + str(int(value[1] / 1024 / 1024)) + " MB)", # shown in dropdown key # data to be saved )) return lis """ "dirname" : singleton.valkkafs_dir.get(), "n_blocks" : 10, "blocksize" : 10 """ columns = [ # TODO: for valkkafs metadata directory: (1) add a non-editable column ColumnSpec(CheckBoxColumn, key_name="record", label_name="Activate recording & playback", def_value=False), ColumnSpec( SpinBoxIntegerColumn, key_name="blocksize", label_name="Blocksize (MB)", min_value=1, max_value=1024 * 1024 * 1024, # 1 GB def_value=default.get_valkkafs_config()["blocksize"]), ColumnSpec(SpinBoxIntegerColumn, key_name="n_blocks", label_name="Number of Blocks", min_value=5, max_value=999999999, def_value=default.get_valkkafs_config()["n_blocks"]), # Calculate Total Size (MB) ColumnSpec(ConstantRadioButtonColumn, key_name="fs_flavor", label_name="ValkkaFS type", list=[("Normal file", "file"), ("Dedicated block device", "valkkafs")]), ColumnSpec(ConstantComboBoxColumn, key_name="partition_uuid", label_name="Available Devices", callback=getValkkaFSDevices) ] # TODO: # Actions (buttons): format, save, cancel (exit without applying changes) def makeWidget(self): """Subclassed from Row : custom form. Add a total disk space field. """ self.widget = FormWidget() self.lay = QtWidgets.QGridLayout(self.widget) cc = 0 self.placeWidget(cc, "record") cc += 1 self.placeWidget(cc, "blocksize") cc += 1 self.placeWidget(cc, "n_blocks") cc += 1 self.label_total_size = QtWidgets.QLabel("Total Size (MB)", self.widget) self.label_total_size_value = QtWidgets.QLabel("", self.widget) self.placeWidgetPair( cc, (self.label_total_size, self.label_total_size_value)) cc += 1 self.placeWidget(cc, "fs_flavor") cc += 1 self.placeWidget(cc, "partition_uuid") cc += 1 self.connectNotifications() def fs_size_changed(): total_size_mb = self["blocksize"].getValue( ) * self["n_blocks"].getValue() self.label_total_size_value.setText(str(total_size_mb)) def block_device_slot(): self["partition_uuid"].updateWidget() n_devs = self["partition_uuid"].widget.count() # QComboBox.count() if n_devs < 1: self["fs_flavor"]["file"].setChecked(True) self["blocksize"].widget.valueChanged.connect(fs_size_changed) self["n_blocks"].widget.valueChanged.connect(fs_size_changed) self["fs_flavor"]["valkkafs"].clicked.connect(block_device_slot) fs_size_changed() block_device_slot() """