diff --git a/settings_ui.py b/settings_ui.py index 7033a8e..1ed8d0a 100644 --- a/settings_ui.py +++ b/settings_ui.py @@ -175,6 +175,23 @@ class LocalModelBox(QGroupBox): self._finished.connect(self._on_finished) self._installed.connect(self._on_installed) + @staticmethod + def _fit_popup(combo): + """Let the list that drops down be as wide as its longest row. + + A combo box hands its own width to the list under it and elides + whatever does not fit, which lands in the middle of the name: + `ggml-org/Qwen....7B-Base-GGUF` is not a model anybody can choose + between. The box itself stays the width the form gave it. + """ + view = combo.view() + view.setTextElideMode(Qt.TextElideMode.ElideNone) + metrics = combo.fontMetrics() + widest = max((metrics.horizontalAdvance(combo.itemText(row)) + for row in range(combo.count())), default=0) + # Room for the frame and for a scroll bar, which a long list will have. + view.setMinimumWidth(widest + view.verticalScrollBar().sizeHint().width() + 24) + @staticmethod def _side_by_side(*widgets): layout = QHBoxLayout() @@ -209,6 +226,7 @@ class LocalModelBox(QGroupBox): self.repo.addItems(list(ggml.SUGGESTED_LLM)) self.repo.setCurrentText(repo or ggml.SUGGESTED_LLM[0]) self.repo.blockSignals(False) + self._fit_popup(self.repo) self._fill_models([]) def showEvent(self, event): @@ -274,6 +292,7 @@ class LocalModelBox(QGroupBox): self.repo.addItems(found) self.repo.setCurrentText(current) self.repo.blockSignals(False) + self._fit_popup(self.repo) return self._fill_models(found) @@ -302,6 +321,7 @@ class LocalModelBox(QGroupBox): index = self.model.findData(wanted) self.model.setCurrentIndex(max(index, 0)) self.model.blockSignals(False) + self._fit_popup(self.model) self._wanted = "" self._model_changed() diff --git a/tests/test_ui.py b/tests/test_ui.py index 1f1a179..b2aa933 100644 --- a/tests/test_ui.py +++ b/tests/test_ui.py @@ -315,6 +315,18 @@ class LocalModels(DikteTest): self.assertIn("2.3 GB", box.status.text()) self.assertNotIn("-", box.status.text()) + def test_a_long_model_name_is_not_cut_in_half(self): + # The list under a combo box takes the box's width and elides what does + # not fit, in the middle: "ggml-org/Qwen....7B-Base-GGUF". + box = self.window(cfg.Config()).local_llm + box.repo.addItem("ggml-org/a-model-with-a-name-that-runs-on-and-on-GGUF") + box._fit_popup(box.repo) + view = box.repo.view() + self.assertEqual(view.textElideMode(), settings_ui.Qt.TextElideMode.ElideNone) + widest = max(box.repo.fontMetrics().horizontalAdvance(box.repo.itemText(row)) + for row in range(box.repo.count())) + self.assertGreaterEqual(view.minimumWidth(), widest) + def test_the_hosted_boxes_go_away_when_the_work_happens_here(self): window = self.window(self.config(transcribe_provider="openai")) self.assertTrue(window.hosted_stt.isVisibleTo(window))